How can i mock a member function of A class in a B class's function?
git45016683 opened this issue · 3 comments
This is a common scenario:
class B has an A object, so class B member function can call class A member function with A object.
so how can i mock class A member function when i perform unit testing on class B member function?
example code like below:
class memberFuncHeader
{
public:
void vOutputValueByPointer(char* p_cStr)
{
p_cStr[0] = 'o'; p_cStr[1] = 'r'; p_cStr[2] = 'i';
p_cStr[3] = 'g'; p_cStr[4] = 'i'; p_cStr[5] = 'n';
}
}
class callMemberFunc
{
public:
int iTest_OutputValueByPointer(char* p_cStr){
m_pObj->vOutputValueByPointer(p_cStr);
return 0;
}
public:
memberFuncHeader* m_pObj;
}
the unit test code like below:
class memberFuncMock {
public:
MAKE_MOCK1(vOutputValueByPointer, void(char*));
};
memberFuncMock memberMock;
callMemberFunc* g_pCallMemberFunc = new callMemberFunc();
int funcCall_OutputValueByPointer(char* p_pcStr) {
int l_iRet = -1;
char l_acStr[256] = {0};
l_iRet = g_pCallMemberFunc->iTest_OutputValueByPointer(l_acStr);
memcpy(p_pcStr, l_acStr, 256);
return l_iRet;
}
TEST_CASE("demo2mockMemberFunc0") {
char* l_pStr = new char[256];
memcpy(l_pStr, "HELLOWORLD", strlen("HELLOWORLD"));
REQUIRE_CALL(memberMock, vOutputValueByPointer(_)).LR_SIDE_EFFECT(memcpy(_1, l_pStr, strlen(l_pStr)));
char l_acStr[256] = { 0 };
int l_iRet = funcCall_OutputValueByPointer(l_acStr);
CHECK(l_iRet == 0);
CHECK(memcmp(l_acStr, "HELLOWORLD", strlen("HELLOWORLD") == 0));
}
I expect iTest_OutputValueByPointer call vOutputValueByPointer mock function and l_acStr equal “HELLOWORLD”, but iTest_OutputValueByPointer actually call class memberFuncHeader function then output 'origin' to l_acStr.
can do this with trompeloeil?
and i push the demo code at demo
You need to make the A member accessible in the test so that you can place an expectation on it. One traditional technique for this is dependency injection, i.e. you create your B with the mocked A for the test.
Yeah, I know what you mean, but that's a real huge workload, because there's a lot of historical code (T_T). And they are running at product....
So, i want to found some solution that can integrated unit testing without requiring too many source code changes。
There are many codes like demo in historical code。Although not the best, but it work。 So i can not change every class to dependency injection。
Thanks。
Well, the library can only work within the rules of the language. For this to work you need:
- To ensure that in the test, the member m_pObj points to a mock object.
- Access to the mock object from the test code, and its type known, at compile time, in the test to be a mock.
With those you can place expectations on the mock and test your code. If those are not acceptable, then I'm afraid I cannot help.