Using Mocks with Networking

  • I have the following system: 1. A 'Messenger' class which is a singleton with the method sendMessageToTcpServer(char const *) which passes a string through a tcp socket to a server running on a different machine. When the different machine sends a message to me over the socket, my messenger class emits a signal called "receivedCPPP(char const *)" with the string as an argument. I have a slot connected to that signal so I can handle it.

    What I want to do is mock the messenger so when I send a specific string, I can tell the mock to emit the signal with the expected response string as an argument without having the different machine attached.

    Here's the test code I have so far. All it does is pretends to make the tcp socket connection. It doesn't really test anything yet.

    class MockMessenger : public Messenger {
        MOCK_METHOD1(sendMessageToTcpServer,void(char const *));
    class MockTcpSocket : public QTcpSocket {
    TEST(TestMessenger,checksConnect) {
        MockMessenger m;
    TEST(TestMessenger,checksTcp) {
        MockTcpSocket s;
    int main(int argc, char** argv) {
        QTcpSocket s;
      // The following line must be executed to initialize Google Mock
      // (and Google Test) before running the tests.
      ::testing::InitGoogleTest(&argc, argv);
      ::testing::InitGoogleMock(&argc, argv);
      return RUN_ALL_TESTS();

    I'm clueless as to how I can make a test suite and be independent of the attached system my code relies on. What can I do to make a test that will let me send a message like "{"mtype":"GIRQ"}" and receive the signal receivedCPPP("Version 1") for instance. Seems like a perfect need for a mock but I'm new to mocks and stubs unfortunately and what I have found so far has not given me enough insight.

    Many thanks for any advice!

  • Lifetime Qt Champion


    What exactly do you want to know about mocks ? How to implement them ? How to use them ?

  • I guess my confusion is regarding both implementing and using in this case. I want to mock my class so when I send a method a string, my test expects to get a signal with a different string returned. As an example, my class Communicator is a singleton and I send a string to the server like this.


    When this happens, I expect get a signal back from the class called

    receivedGIRQ("Version 1")

    This string, "Version 1", was received in real life by the Communicator class from a tcp socket connected to a real life server. In testing I don't want the server there but I want the mocked Communicator class to act as though it received the message from the server and send the signal whenever I pass it the first string.

    I have seen how to expect a specific number of calls, and specify a return value, but not how to expect a signal with a specific string whenever I call a specific method.

    If it helps, this is the header file for the singleton.

    //your code here
    #ifndef MESSAGER_H
    #define MESSAGER_H
    #include <QObject>
    #include "navmessage.h"
    #include <QTcpSocket>
    #include <QTimer>
    #include "singleton.h"
    #include "dialogsplash.h"
    #include "mainwindow.h"
    class MainWindow;
    class IMessenger : public QObject {
        virtual void sendMessageToTcpServer(char const *) = 0;
        virtual void connectToTcpServer() = 0;
        virtual bool isConnected() = 0;
    class Messenger : public IMessenger
        explicit Messenger();
        virtual void sendMessageToTcpServer(char const *) override;
        virtual void connectToTcpServer() override;
        virtual bool isConnected() override;
        virtual ~Messenger() {}
        QTcpSocket *tcpSocket;  // the preset server on the organ
        bool voicingLocked;
        void sendRequest(char const *);
        void connectSeqSignal(MainWindow *);
        void connectDivPistonSignal(MainWindow *);
        QString firstValid;
        QString strmsg,partial,complete;
        bool _connected;
        bool            retryPreset;                    //!< true if we should retry connecting to the preset server
        bool            retrySeq;                       //!< true if we should retry connecting to the seq server
        QTimer *        timer;                          //!< timer used for testing/dev't
        bool            hasValidMessages(QString);
        QString         popFirstValidMessage(QString);
        static Messenger *m_pInstance;
        void receivedGIRP(QVariantMap map);
        void receivedCAPT(QVariantMap map);
        void receivedCPPP(QVariantMap map);
        void receivedGERR(QVariantMap map);
        void receivedSEQR(QVariantMap map);
        void receivedSSTA(QVariantMap map);
        void connectionClosed(QString);
        void messengerError(QString);
        void displayMessage(QString);
        void refreshGVSignal();
        void sequenceStepInfoSignal(QString);
        void sequenceDivisionPistonSignal(QString);
    public slots:
        void refreshGVSlot();
        void sequenceStepInfoSlot(QString);
        void sequenceDivisionPistonSlot(QString);
    private slots:
        //! parses incoming JSON messages from servers; distributes most messages to the active screen
        void readServer();
        //! print the error returned when server closes connection
        void connectionClosedByServer();
        //! timer callback used for debugging only
        void timeout();
        //! slot called on socket errors
        void error(QAbstractSocket::SocketError);
        //! slot used for retrying connection attempts (periodic retries while servers starting up)
        void retryConnect();
    public slots:
        //! called when server is connected; proceed to another connection, or switch to Splash screen.
        void hostConnected();
    typedef Singleton<Messenger> Communicator;
    #endif // MESSAGER_H

  • Lifetime Qt Champion

    Then rather than a QTcpSocket you should have the generic QIODevice.

    Then you can write your MockDevice to answer what you expect and in your code you either set a QTcpSocket when connecting to your real server or your MockDevice if you are testing or just don't have that server available.

  • ok, i'll look into QIODevice, thanks!

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.