我看到了一些关于gmock的示例代码,
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <stdio.h>
#include <string>
class MockFoo {
public:
MockFoo() {}
MOCK_METHOD3(Bar, char(const std::string& s, int i, double x));
MOCK_METHOD2(Bar2, bool(int x, int y));
MOCK_METHOD2(Bar3, void(int x, int y));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
};
class GMockOutputTest : public testing::Test {
protected:
MockFoo foo_;
};
TEST_F(GMockOutputTest, ExpectedCall) {
testing::GMOCK_FLAG(verbose) = "info";
EXPECT_CALL(foo_, Bar2(0, _));
foo_.Bar2(0, 0); // Expected call
testing::GMOCK_FLAG(verbose) = "warning";
}
模拟类MockFoo正在类体中模拟三个函数,但类MockFoo不会继承任何类。
如果我理解正确,模拟类可以模拟虚函数和非虚函数。
1)模拟虚函数:mock类应该继承被模拟的基类,该类中的所有函数都应该是虚函数,但在本例中,没有基类。
2)模拟非虚函数:mock类不需要继承任何类,但需要在代码中添加tamplate才能使用hi-perf依赖注入。
以上代码是否属于任何一种情况?它试图嘲笑的是什么?以及如何理解它?
答案 0 :(得分:1)
这里要记住的关键是模拟类可以覆盖超类中的虚拟或非虚拟方法,但它不会拥有。有时,定义一个完全独立的模拟是有用的,它不符合任何特定的接口或覆盖任何其他功能。考虑一下您正在测试模板化课程的情况:
template <typename T>
class Foo {
public:
Foo(T* member) : _member(member) {}
void f() { _member->bar(); }
private:
T* _member;
};
您想验证类Foo是否在模板参数类上调用bar(),但模板类不需要符合任何正式接口;它只需要暴露一个bar()方法。在这种情况下,您可以使用独立的模拟:
class MockSomething {
public:
MOCK_METHOD0(bar, void());
};
就像你的例子一样,这个mock类与另一个类或接口没有任何关系。它是一个独立的模拟器,它可以像其他任何一样使用:
TEST(StackOverflow, StandaloneMock) {
MockSomething mock;
EXPECT_CALL(mock, bar());
Foo<MockSomething> foo(&mock);
foo.f();
}
答案 1 :(得分:0)
该代码用于测试模板类Bar2()
的方法NaggyMock
。更确切地说,它正在测试当您使用参数Bar2()
和0
调用方法0
时,将调用模拟中的Bar2()
方法。
您可以将其视为静态依赖项注入,因为您通过模板参数注入依赖项。我会说是2。
假设你的模板类NaggyMock看起来像这样:
template< typename Foo >
class NaggyMock
{
public:
bool Bar2(int x, int y)
{
if ( ( 0 == x ) && ( 0 == y ) )
{
return foo.Bar2( 0, 11 );
}
return false;
}
private:
Foo foo;
};
然后在单元测试中,当两个参数均为0时,您正在测试该情况。如果您的真实类正在使用某些资源(从网络读取,或从数据库或文件读取,...),那么要避免它,并使你的单元测试非常快,你将模拟该对象。这就是你在做什么。而不是处理真实资源的类,而是注入一个模拟对象。
有关详细信息,请阅读: