問題描述
眾所周知,在 C++ 中模擬/偽造非虛擬測試方法是很困難的.例如,googlemock 的cookbook 有兩個建議 - 都意味著修改原始源代碼以某種方式(模板化和重寫為界面).
It known that in C++ mocking/faking nonvirtual methods for testing is hard. For example, cookbook of googlemock has two suggestion - both mean to modify original source code in some way (templating and rewriting as interface).
對于 C++ 代碼來說,這似乎是一個非常糟糕的問題.如果您無法修改需要偽造/模擬的原始代碼,如何做得最好?復制整個代碼/類(整個基類層次結構??)
It appear this is very bad problem for C++ code. How can be done best if you can't modify original code that needs to be faked/mocked? Duplicating whole code/class (with it whole base class hierarchy??)
推薦答案
我遵循了 Link Seam 鏈接來自 sdg 的答案.我在那里讀到了不同類型的接縫,但給我印象最深的是預處理接縫.這讓我考慮進一步利用預處理器.事實證明,可以在不實際更改調用代碼的情況下模擬任何外部依賴.
I followed the Link Seam link from sdg's answer. There I read about different types of seams, but I was most impressed by Preprocessing Seams. This made me think about exploiting further the preprocessor. It turned out that it is possible to mock any external dependency without actually changing the calling code.
為此,您必須使用替代依賴項定義編譯調用源文件.這是一個如何做的例子.
To do this, you have to compile the calling source file with a substitute dependency definition. Here is an example how to do it.
依賴.h
#ifndef DEPENDENCY_H
#define DEPENDENCY_H
class Dependency
{
public:
//...
int foo();
//...
};
#endif // DEPENDENCY_H
調用者.cpp
#include "dependency.h"
int bar(Dependency& dependency)
{
return dependency.foo() * 2;
}
test.cpp
#include <assert.h>
// block original definition
#define DEPENDENCY_H
// substitute definition
class Dependency
{
public:
int foo() { return 21; }
};
// include code under test
#include "caller.cpp"
// the test
void test_bar()
{
Dependency mockDependency;
int r = bar(mockDependency);
assert(r == 42);
}
請注意,mock 不需要實現完整的 Dependency
,只需實現最小的(由 caller.cpp 使用)以便測試可以編譯和執行.通過這種方式,您可以在不更改生產代碼的情況下模擬非虛擬、靜態、全局函數或幾乎任何依賴項.我喜歡這種方法的另一個原因是與測試相關的所有內容都在一個地方.您不必到處調整編譯器和鏈接器配置.
Notice that the mock does not need to implement complete Dependency
, just the minimum (used by caller.cpp) so the test can compile and execute.
This way you can mock non-virtual, static, global functions or almost any dependency without changing the productive code.
Another reason I like this approach is that everything related to the test is in one place. You don't have to tweak compiler and linker configurations here and there.
我已成功地將這種技術應用于具有大量依賴項的現實世界項目.我在 Include mock 中更詳細地描述了它.
I have applied this technique successfully on a real world project with big fat dependencies. I have described it in more detail in Include mock.
這篇關于假/模擬非虛擬 C++ 方法的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!