【发布时间】:2017-11-09 10:58:45
【问题描述】:
我想测试一个应用程序Thud,它将使用资源Foo。它不会拥有一个具体的对象,但会有一个指向抽象资源接口的指针(此处为IFoo)。在生产中,我将为它提供实际的资源实现 (FooImpl),而对于单元测试,我想发送一个指向模拟资源的指针。我该怎么做?我试图写最少的代码只是为了指出,
class IFoo
{
public:
virtual bool Foo(bool) = 0;
};
class FooImpl : public IFoo
{
public:
bool Foo(bool b) override
{
return b;
}
};
class FooMock : public IFoo
{
public:
MOCK_METHOD1(Foo, bool(bool));
};
class ThudTest : public ::testing::Test
{
protected:
virtual void SetUp() {
//foo.reset(&mock); //line#1
foo = &mock; //line#2
}
FooMock mock;
//std::shared_ptr<IFoo> foo; //line#3
IFoo* foo; //line#4
};
class Thud
{
//std::shared_ptr<IFoo> fooPtr; //line#5
IFoo* fooPtr; //line#6
public:
/*Thud(std::shared_ptr<IFoo> fooPtr_) : fooPtr{ fooPtr_ }
{}*/ //line#7
Thud(IFoo* fooPtr_) : fooPtr{ fooPtr_ }
{} //line#8
bool thud1(bool b)
{
return fooPtr->Foo(b);
}
};
TEST_F(ThudTest, fooFalse)
{
bool b = false;
EXPECT_CALL(mock, Foo(b)).Times(1).WillOnce(Return(false));;
Thud thud(foo);
EXPECT_FALSE(thud.thud1(b));
}
TEST_F(ThudTest, fooTrue)
{
bool b = true;
EXPECT_CALL(mock, Foo(b)).Times(1).WillOnce(Return(true));;
Thud thud(foo);
EXPECT_TRUE(thud.thud1(b));
}
int main(int argc, char** argv) {
// The following line must be executed to initialize Google Mock
// (and Google Test) before running the tests.
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
所以为了完成,我有一个重载的构造函数,它不需要争论,但会做以下事情,
Thud():fooPtr {std::make_shared<FooImpl>()}
{}
在生产中得到真正的实现。 但是现在我如何使指针指向模拟对象。如您所见,我在这里使用 GMock 框架。如何做到这一点?
如果我注释掉使用普通旧原始指针的第 #2、4、6 和 8 行并取消注释并使用第 1、3、5 和 7 行(在此处使用有问题的 shared_ptr),它会崩溃在第一个测试用例之后出现堆损坏。
它与这个原始指针完美配合。
【问题讨论】:
标签: c++ unit-testing mocking shared-ptr