Mocking free function(模拟免费功能)
问题描述
我遇到了一个问题,似乎找不到解决方案.
我使用 VS2005 SP1 编译代码.
我有一个全局函数:
A* foo();
我有一个模拟课
class MockA : public A {民众:MOCK_METHOD0 (bar, bool());...};
在源代码中,它是这样访问的:foo()->bar()
.我找不到嘲笑这种行为的方法.而且我不能改变来源,所以谷歌模拟烹饪书中的解决方案是不可能的.
任何正确方向的帮助或指示将不胜感激.:)
不,这是不可能的,不改变源代码,或者带上你自己的与可执行代码链接的 foo()
版本.
来自 GoogleMock 的常见问题解答它说
<块引用>我的代码调用了一个静态/全局函数.我可以嘲笑它吗?
你可以,但你需要做一些改变.一般来说,如果您发现自己需要模拟一个静态函数,则表明您的模块耦合过于紧密(灵活性较差、可重用性较差、可测试性较差等).您可能最好定义一个小接口并通过该接口调用该函数,然后可以轻松模拟.最初需要一些工作,但通常很快就会收回成本.
这篇 Google 测试博客 post 说得很好.看看吧.
同样来自食谱
<块引用>模拟免费功能
可以使用 Google Mock 来模拟自由函数(即 C 风格的函数或静态方法).您只需要重写代码即可使用接口(抽象类).不是直接调用自由函数(比如 OpenFile),而是为它引入一个接口并有一个调用自由函数的具体子类:
class FileInterface {
公开:...virtual bool Open(const char* path, const char* mode) = 0;};
<块引用>
class File : public FileInterface {
公开:...virtual bool Open(const char* path, const char* mode) {返回 OpenFile(路径,模式);}};
<块引用>
您的代码应该与 FileInterface 对话以打开文件.现在可以轻松模拟该函数.
这可能看起来很麻烦,但在实践中,您通常可以将多个相关函数放在同一个界面中,因此每个函数的语法开销会低得多.
如果您担心虚函数产生的性能开销,并且分析证实了您的担忧,您可以将其与模拟非虚方法的秘诀结合起来.
正如您在评论中提到的,您实际上提供了自己的 foo()
版本,您可以使用另一个模拟类的全局实例轻松解决这个问题:
struct IFoo {虚拟 A* foo() = 0;虚拟 ~IFoo() {}};结构 FooMock : 公共 IFoo {FooMock() {}虚拟 ~FooMock() {}MOCK_METHOD0(foo, A*());};FooMock fooMock;//你的 foo() 实现A* foo() {返回 fooMock.foo();}测试(...) {EXPECT_CALL(fooMock,foo()).时代(1).WillOnceReturn(new MockA());//...}
不要忘记在每个测试用例运行后清除所有调用预期.
I am stuck in a problem and can't seem to find the solution.
I am using VS2005 SP1 for compiling the code.
I have a global function:
A* foo();
I have a mock class
class MockA : public A {
public:
MOCK_METHOD0 (bar, bool());
...
};
In the sources, it is accessed like this: foo()->bar()
. I cannot find a way to mock this behavior. And I cannot change the sources, so the solution in google mock cook book is out of question.
Any help or pointers in the right direction will be highly appreciated. :)
No it's not possible, without changing the sources, or bringing your own version of foo()
that is linked with the executable code.
From GoogleMock's FAQ it says
My code calls a static/global function. Can I mock it?
You can, but you need to make some changes.In general, if you find yourself needing to mock a static function, it's a sign that your modules are too tightly coupled (and less flexible, less reusable, less testable, etc). You are probably better off defining a small interface and call the function through that interface, which then can be easily mocked. It's a bit of work initially, but usually pays for itself quickly.
This Google Testing Blog post says it excellently. Check it out.
Also from the Cookbook
Mocking Free Functions
It's possible to use Google Mock to mock a free function (i.e. a C-style function or a static method). You just need to rewrite your code to use an interface (abstract class).Instead of calling a free function (say, OpenFile) directly, introduce an interface for it and have a concrete subclass that calls the free function:
class FileInterface {
public:
...
virtual bool Open(const char* path, const char* mode) = 0;
};
class File : public FileInterface {
public:
...
virtual bool Open(const char* path, const char* mode) {
return OpenFile(path, mode);
}
};
Your code should talk to FileInterface to open a file. Now it's easy to mock out the function.
This may seem much hassle, but in practice you often have multiple related functions that you can put in the same interface, so the per-function syntactic overhead will be much lower.
If you are concerned about the performance overhead incurred by virtual functions, and profiling confirms your concern, you can combine this with the recipe for mocking non-virtual methods.
As you mentioned in your comment that you actually provide your own version of foo()
, you can easily solve this having a global instance of another mock class:
struct IFoo {
virtual A* foo() = 0;
virtual ~IFoo() {}
};
struct FooMock : public IFoo {
FooMock() {}
virtual ~FooMock() {}
MOCK_METHOD0(foo, A*());
};
FooMock fooMock;
// Your foo() implementation
A* foo() {
return fooMock.foo();
}
TEST(...) {
EXPECT_CALL(fooMock,foo())
.Times(1)
.WillOnceReturn(new MockA());
// ...
}
Don't forget to clear all call expectations, after each test case run.
这篇关于模拟免费功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:模拟免费功能
基础教程推荐
- 设计字符串本地化的最佳方法 2022-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- C++,'if' 表达式中的变量声明 2021-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01