这是我今天早些时候提出的问题的修订/更好的书面版本 - 现在该问题已被删除。
我有一个项目,我开始使用Google Mock。我创建了一个类,该类调用Windows API中的函数。我还创建了一个包含Windows API的虚函数的包装类,如Google Mock CheatSheet中所述。然而,我很困惑我应该如何将包装器传递给使用该对象的类。显然该对象需要是多态的,所以我不能通过值传递它,迫使我传递一个指针。这本身并不是问题,但我很困惑谁应该拥有指向包装API的类的指针。
那么......我应该如何将包装类传递给真正的类来促进模拟呢?
这是我的意思的一个例子:
struct A {
virtual void SomeMethod(int x, int y)
{
::SomeMethod(x, y);
};
};
class Client
{
A * method_;
public:
Client(A * method = new A) : method_(method) {};
void DoSomething()
{
method_->SomeMethod(42, 34);
}
};
struct Mock : public A
{
MOCK_METHOD2(SomeMethod, void(int, int));
};
TEST(MyTest, MyTestWithMock)
{
Mock * mock = new Mock();
EXPECT_CALL(*mock, SomeMethod(42, 34)).Times(1);
Client client(mock); //Should *client* be responsable for deleting mock?
client.DoSomething();
};
示例2:
struct A {
virtual void SomeMethod(int x, int y)
{
::SomeMethod(x, y);
};
};
class Client
{
A * method_;
public:
Client(A * method) : method_(method) {};
static Client Create()
{
static A;
return Client(&A);
}
void DoSomething()
{
method_->SomeMethod(42, 34);
}
};
struct Mock : public A
{
MOCK_METHOD2(SomeMethod, void(int, int));
};
TEST(MyTest, MyTestWithMock)
{
Mock mock;
EXPECT_CALL(mock, SomeMethod(42, 34)).Times(1);
Client client(&mock);
client.DoSomething();
};
答案 0 :(得分:2)
始终可以选择使用shared_ptr
;这肯定会解决所有权问题。
答案 1 :(得分:0)
许多所有权计划都是可能的,但有些计划比其他计划更易于维护。每当一个对象x
包含另一个y
时,我会问:
谁创建了y
?该方也应该销毁y
。
这种方法的优点是,当一个或两个对象被静态分配时,它的工作原理也一样,而转让所有权的方法必须使用shared_ptr<>
或假设是否y
动态分配与否。前者引入了开销,而后者则是脆弱的。
如果多个方可以创建对象,就像你的代码当前那样(它可以由调用者或构造函数创建为默认参数),到目前为止最简单的方法是使用shared_ptr<>
。但是,如果可能的话,避免不同方可以创建资源的情况是个好主意 - 是“用大象枪射击鼠标”。
答案 2 :(得分:0)
虚拟功能不是执行此操作的唯一方法。您还可以使用有效地为您提供编译时多态性的模板。
struct A {
virtual void SomeMethod(int x, int y)
{
::SomeMethod(x, y);
};
};
template <class T>
class Client
{
T method_;
public:
Client() : method_(method) {};
static Client Create()
{
return Client();
}
void DoSomething()
{
method.SomeMethod(42, 34);
}
T &GetMethod()
{
return method_;
}
};
struct Mock
{
MOCK_METHOD2(SomeMethod, void(int, int));
};
TEST(MyTest, MyTestWithMock)
{
Client<Mock> client;
EXPECT_CALL(client.GetMethod(), SomeMethod(42, 34)).Times(1);
client.DoSomething();
};