Provide gmock-compatible `MOCK_METHOD()` macro
There are a few reasons I think this is worth doing. The most pressing is that it provides compatibility with tools such as protoc which can generate mocks using MOCK_METHOD(). (Users would need to either manually remove the gmock/gmock.h header or shim in their own, but that seems like a small price to pay for generated mocks!)
The other, perhaps more controversial take, is that I think it is actually a better design than the current large family of MAKE_MOCK macros! While it is cool that the MAKE_MOCK family takes a normal C++ function signature type as its argument, it leads to a number of problems:
- MOCK_METHOD is nice in that its
return_type, method_name, (args...), (specs...)_optargument order nicely mirrors a (normal style) function declaration - By having the return type and args separate, and especially by putting the args in
()it makes it easier to process them with macros:- It is trivial to count the number of arguments since there is no return type in the way. Without requiring using
auto(args...) -> retwhich is unusual syntax. - It is easy to remove wrapping
()around the return type and each arg type, so that types with,embedded can just be wrapped up by the user and later removed by the framework. - Having
specsis an easy place to putconstsupport. FWIW, my first guesses wereMAKE_MOCK(x, auto () const -> R)andMAKE_MOCK(x, auto() -> R, const), neither of which worked, so I had to go to the docs to discoverMAKE_CONST_MOCK(). Ditto forstdcallsupport which combines withconstto generate a 4x combinatorial explosion of macros for users to know about!
- It is trivial to count the number of arguments since there is no return type in the way. Without requiring using
- I think it would be relatively straight-forward to translate it into a call to your existing
TROMPELOEIL_MAKE_MOCK_(name, constness, callconv, num, sig, spec, ...)implementation macro. Although it might need some enhancements to support mocking&&-qualified methods.- sidenote: I see that that macro takes
..., but it doesn't seem to use__VA_ARGS__. Is that a bug or are extra arguments intentionally ignored?
- sidenote: I see that that macro takes
I could also see naming the macro something else like MAKE_MOCK_METHOD() or just MOCK() to avoid name conflicts with gmock and then let users who want to alias it do their own #define MOCK_METHOD(...) MOCK(__VA_ARGS__). But I think as much as possible, it would be great if the actual preprocessor shenanigans were done by trompeloeil. In part because you already have things like TROMPELOEIL_COUNT_COMMA and TROMPELOEIL_REMOVE_PAREN, and in part because it may need to expand to use other internal details.