Mockingbird c++ mocking framework

I have developed Mockingbird a mocking framework for c++, it depends on function injection, here is the code from the repository:

/*
*  Mockingbird is a simple and a powerful mocking framework for c++.
*  Copyright (c) Mouaz Chamieh April 2021.
*  https://github.com/muazsh/Mockingbird
*/

#pragma once
#ifndef MOCKINGBIRD
#define MOCKINGBIRD

#define START_MOCK(MockingClass, MockedClass)\
class MockingClass : public MockedClass {\
public:

#define INJECTION_SET(FuncName, Substitute)\
private:\
template<class T>\
class FuncName##Class {\
public:\
FuncName##Class():m_func((T)Substitute){}\
T m_func;\
};\
FuncName##Class<decltype(Substitute)> m_##FuncName##Class;\
mutable int m_##FuncName##CallCounter = 0;\
public:\
void Inject##FuncName(decltype(Substitute) sub){\
m_##FuncName##Class.m_func = sub;}\
int Get##FuncName##CallCounter(){return m_##FuncName##CallCounter;}

#define FUNCTION(FuncName,ReturnType, Signature, Substitute, .../*signature variables*/)\
INJECTION_SET(FuncName, Substitute)\
ReturnType FuncName Signature override\
{ m_##FuncName##CallCounter++;\
return m_##FuncName##Class.m_func(__VA_ARGS__);}

#define CONST_FUNCTION(FuncName,ReturnType, Signature, Substitute, .../*signature variables*/)\
INJECTION_SET(FuncName, Substitute)\
ReturnType FuncName Signature const override\
{ m_##FuncName##CallCounter++;\
return m_##FuncName##Class.m_func(__VA_ARGS__);}

private:\
public:\
void Inject##FuncName(decltype(Substitute) sub){\

ReturnType FuncName Signature override\

ReturnType FuncName Signature const override\

#define END_MOCK(MockingClass)\
};

#endif // !MOCKINGBIRD


and here is an example on how it works:

Assume you have the following class Foo and you need to mock:

struct MyStruct{
int x, y;
};

class Foo{
public:
virtual const MyStruct CreateMyStruct(int x, int y) { return MyStruct{ x,y }; }
};


Then you write a testing fixture only once for the whole project:

const MyStruct CreateMyStructDummy(int x, int y) { return MyStruct{0,0}; }

START_MOCK(FooMock, Foo)
FUNCTION(CreateMyStruct, const MyStruct, (int x, int y), &CreateMyStructDummy, x, y)
END_MOCK(FooMock)


Then in the tests you write the desired substitute for example:

const MyStruct CreateMyStructSubstitute(int x, int y) { return MyStruct{ x + 10, y + 10 }; }


and inject it like:

FooMock fooMock;
fooMock.InjectCreateMyStruct(CreateMyStructSubstitute); // Mocking function injection.
auto created = fooMock.CreateMyStruct(5,5);
EXPECT_EQ(created.x, 15);
EXPECT_EQ(created.y, 15);


The code is in the file Mockingbird.hpp and totally depends on macros, it is short and straightforward, I ask for reviewing the code on github here, thanks.

• @pacmaninbw I see, in this case what about the license once I post my code in here, I have read some questions like this but it is too old and not sure if this is still valid or even it can be dragged to codereview community. – muaz Apr 19 at 20:09
• @muaz IANAL TINLA. By posting you submit the code under CC BY-SA 4.0 and MIT (if you include the license and stuff) revewers have the option to provide answers only in CC BY-SA 4.0. If a reviewer submits an only CC BY-SA answer you can ask the answerer nicely to allow you to use the code as MIT. – Peilonrayz Apr 19 at 21:04
• Posting to stackexchange puts the code available on SE under the CC-BY-SA-4.0 license, so long as you have the rights to perform such a licensing. Users of the code could then choose which license they'd use. For MIT that would require carrying over the MIT license declaration, for CC-BY that requires licensing derivative works under CC-BY and attributing to the original author. – Vogel612 Apr 19 at 21:04
• Welcome to Code Review! Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see What should I do when someone answers my question? as well as what you may and may not do after receiving answers. – Sᴀᴍ Onᴇᴌᴀ Apr 20 at 21:07
• Another reason for not updating the code after an answer has been posted is that everyone should see what the person writing the review saw so they understand the review. – pacmaninbw Apr 20 at 21:22

You make the code really hard to read:

#define INJECTION_SET(FuncName, Substitute)\
private:\
template<class T>\
class FuncName##Class {\
public:\
FuncName##Class():m_func((T)Substitute){}\
T m_func;\
};\
FuncName##Class<decltype(Substitute)> m_##FuncName##Class;\
mutable int m_##FuncName##CallCounter = 0;\
public:\
void Inject##FuncName(decltype(Substitute) sub){\
m_##FuncName##Class.m_func = sub;}\
int Get##FuncName##CallCounter(){return m_##FuncName##CallCounter;}


just because it is a macro does not mean it needs to be unreadable. You can still format it nicely for the maintainer.

#define INJECTION_SET(FuncName, Substitute)                         \
\
private:                                                        \
template<class T>                                               \
class FuncName##Class                                           \
{                                                               \
public:                                                     \
FuncName##Class():m_func((T)Substitute){}               \
T m_func;                                               \
};                                                              \
\
FuncName##Class<decltype(Substitute)> m_##FuncName##Class;      \
\
mutable int m_##FuncName##CallCounter = 0;                      \
public:                                                         \
void Inject##FuncName(decltype(Substitute) sub)                 \
{                                                               \
m_##FuncName##Class.m_func = sub;                           \
}                                                               \
int Get##FuncName##CallCounter()                                \
{                                                               \
return m_##FuncName##CallCounter;                           \
}

• I think the unreadability goes a long way towards explaining why it sat for two days waiting for a reviewer. It certainly discouraged me. – Toby Speight Apr 20 at 20:07
• Okay thanks I edited and reformatted code, I hope it is more readable now. – muaz Apr 20 at 21:01