trompeloeil icon indicating copy to clipboard operation
trompeloeil copied to clipboard

Poor compilation error messages with mock mismatch in expectation

Open rollbear opened this issue 10 years ago • 1 comments

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.

rollbear avatar Nov 22 '15 15:11 rollbear

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.

rollbear avatar Jan 02 '16 14:01 rollbear