如何使用shared_ptr从外部提供mock对象
How to use shared_ptr to supply mock object from outside?
我想测试一个应用程序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>()}
{}
以在生产中获得真正的实施。但是现在我该如何使指针指向mock对象。正如您所看到的,我在这里使用的是GMock框架。如何做到这一点?
如果我评论掉第2,4,6&8,它使用一个普通的旧原始指针并取消注释并使用第#1,3,5&7(此处使用有问题的shared_ptr
),在第一个测试用例之后,它会因堆损坏而崩溃。
它与这个原始指针完美配合。
您不能执行foo.reset(&mock)
,因为mock
有两个所有者:它的自动存储持续时间,加上共享指针foo
。内存损坏FTW。
您应该简单地动态分配FooMock
,并在创建正在测试的Thud
实例时将其传入:
class ThudTest : public ::testing::Test
{
protected:
virtual void SetUp() {
foo = std::make_shared<FooMock>();
}
std::shared_ptr<FooMock> foo;
};
您甚至不再需要mock
成员了。请注意,我已经更改了foo
的类型以了解FooMock
,这样您就可以访问该类型。如果你真的想让foo
保持mock不知情,可以这样做:
class ThudTest : public ::testing::Test
{
protected:
virtual void SetUp() {
mock = std::make_shared<FooMock>();
foo = mock;
}
std::shared_ptr<FooMock> mock;
std::shared_ptr<IFoo> foo;
};
然而,这不应该是必要的,因为std::shared_ptr<FooMock>
可以隐式转换为std::shared_ptr<IFoo>
。
带有:
class Thud
{
std::shared_ptr<IFoo> fooPtr;
public:
Thud(std::shared_ptr<IFoo> fooPtr_) : fooPtr{ fooPtr_ }
{}
bool thud1(bool b)
{
return fooPtr->Foo(b);
}
};
你的测试可以变成(我删除了这个功能):
TEST(ThudTest, fooFalse)
{
auto mock = std::make_shared<FooMock>()
bool b = false;
EXPECT_CALL(*mock, Foo(b)).Times(1).WillOnce(Return(false));;
Thud thud(mock);
EXPECT_FALSE(thud.thud1(b));
}
TEST(ThudTest, fooTrue)
{
auto mock = std::make_shared<FooMock>()
bool b = true;
EXPECT_CALL(*mock, Foo(b)).Times(1).WillOnce(Return(true));;
Thud thud(mock);
EXPECT_TRUE(thud.thud1(b));
}
在我的解决方案中,a需要使用shared_ptr<IFoo>
将其添加到其他测试类的集合中,我发现使用了refercene;)。然后我尝试了NiceMock<IFoo>
和StrictMock<IFoo>
,它也起作用了。
using namespace testing;
using namespace std;
class ThudTest : public Test {
public:
shared_ptr<FooMock> fooPtr_ = make_shared<FooMock>();
// shared_ptr<StrictMock<FooMock>> fooPtr_ = make_shared<StrictMock<FooMock>>();
FooMock& mock = *fooPtr_;
// StrictMock<FooMock>& mock= *fooPtr_;
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));
EXPECT_FALSE(thud1(b));
}
TEST_F(ThudTest, fooTrue) {
bool b = true;
EXPECT_CALL(mock, Foo(b)).Times(1).WillOnce(Return(true));
EXPECT_TRUE(thud1(b));
}
- 什么时候调用组成单元对象的析构函数
- 如何使用Google Mock来模拟gettimeofday()
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 如何使用shared_ptr从外部提供mock对象
- 将GoogleMock与Boost::Shared Pointers一起使用时泄漏的Mock对象
- 如何使用Google Mock更改指定对象的类型
- 无法创建mock类/对象来替换我的类中的私有成员对象的功能,以便在gtest中进行单元测试
- 使用Google Mock来模拟在客户端代码中复制的对象
- c++, google test/mock:测试和对象类型的断言
- Google Mock:在程序出口处发现泄漏的模拟对象
- 单元测试——不直接使用被模拟对象的Google Mock (c++)
- 从Google mock中的模拟对象返回一个模拟对象