【发布时间】:2016-04-15 20:27:22
【问题描述】:
我正在测试一些大量使用回调的代码,它看起来像这样:
class Client {
public:
Client(Socket socket) {
socket->onA([this] {
// call private Client methods....
});
socket->onB([this] {
// call private Client methods...
});
// repeated for onC, onD, and onE
}
void Start();
void Stop();
private:
// and almost all of the state is private
};
它几乎完全通过Socket提供的接口与外界通信,看起来像:
class Socket {
public:
void onA(std::function<void()> callBack) = 0;
void onB(std::function<void()> callBack) = 0;
void onC(std::function<void()> callBack) = 0;
void onD(std::function<void()> callBack) = 0;
void onE(std::function<void()> callBack) = 0;
// various other public methods
};
重要的是我既可以验证onX 函数是否已被调用,又可以访问传递给它们的参数(因为Client 的状态会根据Socket 的通知而改变,我需要在我的测试中模拟这些)。
我可以写一个看起来像这样的模拟:
class MockSocket : public Socket {
public:
MOCK_METHOD1(onA, void(std::function<void()> callBack));
MOCK_METHOD1(onB, void(std::function<void()> callBack));
// etc
};
但是我需要能够写出对表单的期望:“期望这个MockSocket对象有它的onA方法调用一次,现在调用作为参数传递给onA的函数。现在检查Socket 的 write 方法是用这个字符串调用的:...."
在另一种情况下,当我只有一个此类功能时,我做了类似的事情:
class MockSocket : public Socket {
public:
// as before
void setCallbackForA(std::function<void()> callBack) {
callbackForA = callBack;
}
void callCallbackForA() {
callbackForA();
}
// etc
private:
std::function<void()> callbackForA;
std::function<void()> callbackForB;
// etc
};
但这将是一个荒谬的样板数量来完成这项工作(5 个 getter 和 5 个 setter + 所有 EXPECT_CALLs,从测试用例到测试用例会非常轻微),我怀疑必须有一个更好的方法来做到这一点(不诉诸C风格的宏)。有一些模板魔法可以提供帮助吗?有什么可以让它更容易处理的吗?
【问题讨论】:
标签: c++ unit-testing mocking googletest googlemock