gpt4 book ai didi

c++ - 轻松编写保持状态的模拟

转载 作者:行者123 更新时间:2023-11-30 03:42:46 24 4
gpt4 key购买 nike

我正在测试一些大量使用回调的代码,它看起来像这样:

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提供的接口(interface),看起来像:

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 的参数。现在检查是否使用此字符串调用了 Socketwrite 方法:...”

在另一种情况下,当我只有一个此类功能时,我做了类似的事情:

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_CALL,从一个测试用例到另一个测试用例会非常轻微),我怀疑必须有更好的方法来做到这一点(不求助于 C 风格的宏)。是否有一些模板魔术可以提供帮助?有什么可以让它更容易处理的吗?

最佳答案

我假设您正在测试 Client类 - 所以你真正需要的是存储 Client 的回调函数在 Socket 注册.通过 SaveArg<N> 执行此操作行动。见代码:

class ClientTest : public ::testing::Test
{
public:
std::function<void()> onACallback;
std::function<void()> onBCallback;
//...
MockSocket mockSocket;
std::unique_ptr<Client> objectUnderTest;
void SetUp() override
{
using ::testing::SaveArg;
EXPECT_CALL(mockSocket, onA(_)).WillOnce(SaveArg<0>(&onACallback));
EXPECT_CALL(mockSocket, onB(_)).WillOnce(SaveArg<0>(&onBCallback));
//...
objectUnderTest = std::make_unique<Client>(mockSocket);

}
};

使用上面的测试类 - 您可以收集所有回调。您可以使用这些捕获的回调来触发 Client 类中的操作,如下面的测试用例所示:

TEST_F(ClientTest, shallDoThisAndThatOnA)
{
// here you put some expectations
//...
onACallback(); // here you trigger your Client object under test
// now you make some assertions (post actions)
//...
}

关于c++ - 轻松编写保持状态的模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36656259/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com