首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GMock -在预期的调用后执行操作

GMock -在预期的调用后执行操作
EN

Stack Overflow用户
提问于 2021-06-05 00:31:43
回答 1查看 29关注 0票数 0

我正在尝试执行一个单元测试,我需要我的模拟对象在一系列EXPECT_CALLS之后执行一个操作,或者作为其中一个序列上的操作,同时允许模拟的调用首先返回。

下面是我的非工作单元测试:

代码语言:javascript
复制
class MockWebSocket : public alert::QWebSocketInterface
{
public:
    MOCK_METHOD(void, open, (QUrl const&), (override));
    MOCK_METHOD(void, close, (QWebSocketProtocol::CloseCode, QString const&), (override));
    MOCK_METHOD(qint64, sendTextMessage, (QString const&), (override));
    MOCK_METHOD(QAbstractSocket::SocketState, state, (), (const, override));
    MOCK_METHOD(QString, origin, (), (const, override));
    MOCK_METHOD(QString, errorString, (), (const, override));
};

/*!
 * @brief Defines a custom action, where we can invoke methods that were unrelated to a mock object's "expected call"
*/
ACTION_P3(InvokeUnrelatedMethodWith1Arg, classPointer, pointerToMemberFunc, first)
{
    (classPointer->*pointerToMemberFunc)(first);
    return 0;  // This is being used as a return value from the mocked call. I want this action done AFTER the return instead!
};

/*
* @brief Test - Test if the state of the client is 'connected' after the CONNECTED frame is received
* Procedure:
*     Call connect
*     emit connected signal
*     Send the CONNECT stomp frame
*     Have the mock socket send back a CONNECTED stomp frame
*     Check state
* Expected Results:
*     State is CONNECTED
*/
TEST(ClientTests, ConnectedStateAfterConnectedFrame)
{
    QByteArray connectedFrame =
        "CONNECTED\n"
        "version:1.2\n"
        "session:714e58fb\n"
        "server:ActiveMQ-Artemis/2.14.0\n"
        "heart-beat:0,30000\n\n"
    "\0";

    auto mockWebsocket = std::make_shared<MockWebSocket>();
    {
        InSequence sequence;
        EXPECT_CALL(*mockWebsocket, close(_, _)).Times(1);
        EXPECT_CALL(*mockWebsocket, open(_))
            .Times(1)
            .WillOnce(InvokeWithoutArgs(mockWebsocket.get(), &MockWebSocket::connected));
        EXPECT_CALL(*mockWebsocket, sendTextMessage(_))
            .Times(1)
            .WillOnce(DoAll(
                Invoke([](QString message) {return message.size();}),
                InvokeUnrelatedMethodWith1Arg(mockWebsocket.get(), &MockWebSocket::binaryMessageReceived,connectedFrame)
            ));

        // Close is called during cleanup, so we have to allow more calls explicitly
        EXPECT_CALL(*mockWebsocket, close(_, _)).Times(AtLeast(1));
    }

    auto client = std::make_unique<StompClientSideConnection>(mockWebsocket);
    client->connect(QUrl("ws://localhost:5000"));
    EXPECT_EQ(client->getState(), StompClientSideConnection::State::CONNECTING);
}

这里的问题是,我在DoAll中执行的调用是在模拟方法返回之前执行的。返回值需要是消息的大小。

我需要在模拟调用返回后执行我的自定义操作。目前,我得到了模拟sendTextMessage的返回值0。

测试注释中描述了必须发生的事件的顺序。我想假装我正在模拟的套接字收到了响应我的连接请求的适当消息。有没有办法在模拟调用返回后执行操作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-06 03:21:26

套接字通常是异步行为的(即,信号在调用方法之后的某个不确定时间发出),但您正在设置模拟对象,使其同步行为(信号在调用方法后立即发出)。您应该尝试模拟异步行为。

通常,您可以通过手动调用信号来实现此行为(而不是作为invoke子句的一部分):

代码语言:javascript
复制
TEST(ClientTests, ConnectedStateAfterConnectedFrame)
{
    QByteArray connectedFrame =
        "CONNECTED\n"
        "version:1.2\n"
        "session:714e58fb\n"
        "server:ActiveMQ-Artemis/2.14.0\n"
        "heart-beat:0,30000\n\n"
    "\0";

    auto mockWebsocket = std::make_shared<MockWebSocket>();
    {
        InSequence sequence;
        EXPECT_CALL(*mockWebsocket, close(_, _)).Times(1);
        EXPECT_CALL(*mockWebsocket, open(_))
            .Times(1)
            .WillOnce(InvokeWithoutArgs(mockWebsocket.get(), &MockWebSocket::connected));
        EXPECT_CALL(*mockWebsocket, sendTextMessage(_))
            .Times(1)
            .WillOnce(DoAll(
                Invoke([](QString message) {return message.size();}),
            ));

        // Close is called during cleanup, so we have to allow more calls explicitly
        EXPECT_CALL(*mockWebsocket, close(_, _)).Times(AtLeast(1));
    }

    auto client = std::make_unique<StompClientSideConnection>(mockWebsocket);
    client->connect(QUrl("ws://localhost:5000"));

    emit mockWebsocket->binaryMessageReceived(connectedFrame);

    EXPECT_EQ(client->getState(), StompClientSideConnection::State::CONNECTING);
}

您可能还需要考虑将此测试分成两个测试:一个测试客户端是否正确地启动了新连接,另一个测试客户端是否可以处理来自套接字的响应。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67840889

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档