class CSumWnd : public CBaseWnd
{
private:
bool MethodA()
}
請你能幫如何嘲笑MethodA()
未做虛擬, 我不明白的hi-perf dependency injection
class CSumWnd : public CBaseWnd
{
private:
bool MethodA()
}
請你能幫如何嘲笑MethodA()
未做虛擬, 我不明白的hi-perf dependency injection
這意味着概念你將不得不對你的生產代碼進行模板化。使用你的例子:
CSumWind
類定義:
class CSumWnd : public CBaseWnd
{
private:
bool MethodA()
};
嘲笑CSumWnd
類的定義:它必須與嘲笑類CSumWind
測試
class MockCSumWnd : public CBaseWnd
{
private:
MOCK_METHOD(MethodA, bool());
};
生產類。現在它成爲在測試中使用CSumWind
類生產代碼和MockCSumWnd
類的模板。在生產
template <class CSumWndClass>
class TestedClass {
//...
void useSumWnd(const CSumWndClass &a);
private:
CSumWndClass sumWnd;
};
實例化:
實例化對象的TestedClass <CSumWnd> obj;
測試可執行文件:
TestedClass <MockCSumWnd> testObj;
嘗試CppFreeMock和其他一些人提到here。
例子:
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());
}
如果你不想改變現有的代碼,這裏是VC特定的解決方案++我的工作(https://github.com/mazong1123/injectorpp)。簡要步驟如下:
讓我們把關鍵代碼放在這裏。
檢索方法的符號和類的地址。以下是實施的關鍵思想。完整的源代碼是在availiable 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 < numChildren; ++i)
{
ULONG curChild = methods->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);
}
步驟2是繁瑣。這只是文本比較和處理。
如何注入魔力ASM改變方法的行爲:(完整的源代碼可在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);
}
看起來很有趣。我很想看到GCC/Clang類似的東西。 – hedayat 2017-09-02 10:28:04
@hedayat我打算這樣做。最近我幾乎完成了x86 Windows部分。保持調諧。 – 2017-10-01 06:39:03
爲了讓您的「生產」代碼乾淨,我發現它有用執行此操作: template class TestedClassTemplate {...},然後執行typedef TestedClassTemplate TestedClass; –
smehmood
2011-04-28 19:28:53
請參閱http://stackoverflow.com/q/1127918/49972瞭解您提出建議後果的信息。 – 2011-05-26 20:19:57
我在'MOCK_METHOD(MethodA,bool())中遇到問題;''https://stackoverflow.com/questions/46542373/how-to-mock-non-virtual-methods-using-googlemock?noredirect=1#comment80038793_46542373我收到上述問題中指定的錯誤 – CMouse 2017-10-03 10:33:44