I have some code:
boost::system::error_code clock_error;
const boost::chrono::steady_clock::time_point START =
boost::chrono::steady_clock::now(clock_error);
and I want to mock the now() function so my test code contains this:
boost::chrono::steady_clock::time_point start(boost::chrono::seconds(0));
boost::system::system_error clock_error(1, BOOST_CHRONO_SYSTEM_CATEGORY, "foo");
mocks.ExpectCallFuncOverload( (boost::chrono::steady_clock::time_point (boost::chrono::steady_clock::*) (boost::system::error_code& clock_error))
&boost::chrono::steady_clock::now)
.With(Out(clock_error))
.Return(start);
but this doesn't compile. I get this error:
error: no matches converting function ‘now’ to type ‘boost::chrono::steady_clock::time_point (class boost::chrono::steady_clock::)(class boost::system::error_code&) {aka class boost::chrono::time_pointboost::chrono::steady_clock (class boost::chrono::steady_clock::)(class boost::system::error_code&)}’ mocks.ExpectCallFuncOverload(
In file included from ...
note: candidates are: static boost::chrono::steady_clock::time_point boost::chrono::steady_clock::now(boost::system::error_code&)
static BOOST_CHRONO_INLINE time_point now(system::error_code & ec); ^
../../../KACotsCode/boost/boost/chrono/system_clocks.hpp:162:46: note: static boost::chrono::steady_clock::time_point boost::chrono::steady_clock::now() static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT;
^
Can anybody spot the problem?
I looked at HippoMocks. That stuff is very high-tech. I would probably not trust it for production code, since it is very intrusive and completely undocumented¹
However, it does do some impressive stuff on GCC and - judging from the code - MSVC:
#define BOOST_CHRONO_HEADER_ONLY
#include "https://raw.githubusercontent.com/dascandy/hippomocks/master/HippoMocks/hippomocks.h"
#include <boost/chrono.hpp>
#include <iostream>
namespace chrono = boost::chrono;
using Clock = chrono::steady_clock;
int main() {
MockRepository mocks;
boost::system::error_code clock_error = make_error_code(boost::system::errc::file_exists);
mocks
.ExpectCallFunc(Clock::now) //
.With(Out(clock_error)) //
.Return(Clock::time_point::max());
auto START = Clock::now(clock_error);
std::cout //
<< clock_error.message() << ": " //
<< std::hex << START.time_since_epoch().count() << std::endl;
}
Prints the expectable
File exists: 7fffffffffffffff
Going back to 2015 (Boost 1.59 August 13th and GCC 4.8.5 June 23rd):
#define BOOST_CHRONO_HEADER_ONLY
#include "https://raw.githubusercontent.com/dascandy/hippomocks/master/HippoMocks/hippomocks.h"
#include <boost/chrono.hpp>
#include <iostream>
namespace chrono = boost::chrono;
using Clock = chrono::steady_clock;
int main() {
std::cout << "Boost version: " << BOOST_VERSION << std::endl;
std::cout << "GCC version: " << __VERSION__ << std::endl;
MockRepository mocks;
boost::system::error_code clock_error = make_error_code(boost::system::errc::file_exists);
mocks
.ExpectCallFunc(static_cast<Clock::time_point (&)(boost::system::error_code&)>(Clock::now)) //
.With(Out(clock_error)) //
.Return(Clock::time_point::max());
auto START = Clock::now(clock_error);
std::cout //
<< clock_error.message() << ": " //
<< std::hex << START.time_since_epoch().count() << std::endl;
}
As you correctly surmised you have to explicitly coerce the overloaded function type. More importantly, HippoMocks doesn't like when you pass the function pointer here, so be sure to case to a function reference: static_cast<Clock::time_point (&)(boost::system::error_code&)>(Clock::now)
Proof of the pudding:
Boost version: 105900
GCC version: 4.8.5
File exists: 7fffffffffffffff
¹ the devs believing that somehow "unfortunately, concise documents restrict access and hinder progress for some developers" [sic]
² Compiler Explorer cannot execute the code because Boost System only became header-only in Boost 1.69.0