trompeloeil
trompeloeil copied to clipboard
Poor compilation error messages with mock mismatch in expectation
Some examples:
class C
{
MAKE_MOCK1(foo, void(int));
void bar(int);
};
TEST(a_test)
{
C obj;
REQUIRE_CALL(obj, foo(3)); // OK
REQUIRE_CALL(obj, foo("")); // type mismatch
REQUIRE_CALL(obj, bar(3)); // not a mock
REQUIRE_CALL(obj, baz(3)); // no such function
}
All the above gives hideous compilation errors that should be possible to make more succinct.
A promising technique is:
template <typename C, typename F>
auto can_call(C* c, F&& f) -> decltype(f(c), std::true_type{}) { return {}; }
template <typename F>
auto can_call(const void*, F&&) -> std::false_type{} { return {}; }
#define CAN_CALL(obj, func) can_call(&(obj), [](auto p) -> decltype(p->func) {});
It could be used to test:
CAN_CALL(obj, foo("")) // -> std::false_type
CAN_CALL(obj, foo(3)) // -> std::true_type
However, all my attempts to use this when creating the expectation object have so far failed to produce any better/shorter compilation errors. It's a bit tricky... assistance highly desired.
This is largely addressed by commit 76499fd5c41f38a3059fb5c1a35abaaf86d719e5
It gives a good message for what's wrong and where the error is, when the expectation does not match any signature, or is ambiguous, for the mock object. The message is a bit too verbose with many secondary errors following. It also fails to provide good information if the signature does match, but is not a mock.
Perhaps this is good enough?
I have written a better solution, based on the idea outlined initially, but unfortunately clang++ is the only compiler I've tried that it works for. Both g++ and VisualStudio 2015 fails miserably, and in completely different ways.