I have class
class CSumWnd : public CBaseWnd { private: bool MethodA() } Please can you help how to mock MethodA() without making virtual, I didn't understand the concept of hi-perf dependency injection
I have class
class CSumWnd : public CBaseWnd { private: bool MethodA() } Please can you help how to mock MethodA() without making virtual, I didn't understand the concept of hi-perf dependency injection
It means you will have to templatize your production code. Using your example:
CSumWind class definition:
class CSumWnd : public CBaseWnd { private: bool MethodA() }; Mocked CSumWnd class definition:
class MockCSumWnd : public CBaseWnd { private: MOCK_METHOD(MethodA, bool()); }; Production class which have to be tested with mocked class CSumWind. Now it becomes templated to provide using CSumWind class in production code and MockCSumWnd class in tests.
template class TestedClass { //... void useSumWnd(const CSumWndClass &a); private: CSumWndClass sumWnd; }; Instantiation of TestedClass in production:
TestedClass obj; Instantiation of TestedClass object in test executable:
TestedClass testObj; Try CppFreeMock and some others mentioned here.
Example:
string func() { return "Non mocked."; } TEST(HelloWorld, First) { EXPECT_CALL(*MOCKER(func), MOCK_FUNCTION()).Times(Exactly(1)) .WillOnce(Return("Hello world.")); EXPECT_EQ("Hello world.", func()); } If you don't want to change the existing code, here is a specific solution for VC++ I'm working on (https://github.com/mazong1123/injectorpp). The brief steps are:
Let's put key code here.
Retrieve methods' symbols and addresses of a class. Below is the key idea of the implementation. The full source code is availiable at https://github.com/mazong1123/injectorpp/blob/master/injectorpp/ClassResolver.cpp
// Retrieve class symbol. if (SymGetTypeFromName(this->m_hProcess, modBase, className.c_str(), classSymbol) == FALSE) { throw; } // Get children of class - which are methods. DWORD numChildren = 0; if (SymGetTypeInfo(this->m_hProcess, classSymbol->ModBase, classSymbol->TypeIndex, TI_GET_CHILDRENCOUNT, &numChildren) == FALSE) { throw; } // Get methods info. if (SymGetTypeInfo(this->m_hProcess, classSymbol->ModBase, classSymbol->TypeIndex, TI_FINDCHILDREN, methods) == FALSE) { throw; } // Retrieve all methods. for (DWORD i = 0; i ChildId[i]; // Resolve function. Function resolvedFunction; this->m_functionResolver->Resolve(classSymbol->ModBase, curChild, resolvedFunction); // Add the resolved function to the output. resolvedMethods.push_back(resolvedFunction); } Step 2 is trival. It's only text comparing and processing.
How to inject the magic asm to change the method behavior: (The full source code is available at https://github.com/mazong1123/injectorpp/blob/master/injectorpp/BehaviorChanger.cpp)
// A magic function to change the function behavior at runtime // // funcAddress - The address of the function to be changed from. // expectedReturnValue - The return value should be changed to. void BehaviorChanger::ChangeFunctionReturnValue(ULONG64 funcAddress, int expectedReturnValue) { // The purpose of this method is to change the return value // to what ever int value we expected. // Therefore, we just need to inject below asm to the header of specific function: // // mov eax, expectedValue // ret // // Above asm code tells the function to return expectedValue immediately. // Now let's prepare the asm command. byte asmCommand[6]; // mov asmCommand[0] = 0xB8; // The value. asmCommand[1] = expectedReturnValue & 0xFF; asmCommand[2] = (expectedReturnValue >> 8) & 0xFF; asmCommand[3] = (expectedReturnValue >> 16) & 0xFF; asmCommand[4] = (expectedReturnValue >> 24) & 0xFF; // ret asmCommand[5] = 0xC3; WriteProcessMemory((HANDLE)-1, (void*)funcAddress, asmCommand, 6, 0); }