c++ - 模拟免费功能

标签 c++ unit-testing tdd googlemock

我遇到了一个问题,似乎找不到解决方案。

我正在使用 VS2005 SP1 编译代码。

我有一个全局函数:

A* foo();

我有一个模拟课

class MockA : public A {
public:
    MOCK_METHOD0 (bar, bool());
    ...
};

在源代码中,它是这样访问的:foo()->bar()。我找不到一种方法来模拟这种行为。而且我无法更改来源,因此 google mock cook book 中的解决方案是毫无疑问的。

任何正确方向的帮助或指示将不胜感激。 :)

最佳答案

不,这是不可能的,如果不更改源代码,或者带来与可执行代码链接的您自己的 foo() 版本。


来自 GoogleMock's FAQ它说

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.

同样来自 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.


正如您在评论中提到的,您实际上提供了自己的 foo() 版本,您可以使用另一个模拟类的全局实例轻松解决此问题:

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());
    // ...
}

不要忘记在每次测试用例运行后清除所有调用期望。

关于c++ - 模拟免费功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28668892/

相关文章:

c++ - 在模板化类中返回模板变量的方法?

javascript - Jest : select an HTML element through innerHTML

testing - 在 TDD 中,谁编写测试 - 开发人员或 QA/测试人员?

java - 对于接受类似类型的输入参数、相同的实现代码但不同的输出的测试用例,正确的实现是什么

c++ - 可以吗在 Google 测试框架内的 TDD 周期中使用全局数据进行多个测试?

c++ - 在 Visual Studio 2012 中从一个项目引用另一个项目中的 DLL

在我的简单测试中,Java 在递归算法速度比较中击败了 C++

c++ - 使用 Google Mocks,如何在不关心/设置任何调用期望的情况下给出模拟实现

ios - 如何在 Swift 中 stub URLSession?

c++ - 无法在 visual studio 2012 中捕获 "ctor subscript out of range"异常