Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Using Mocks with Networking
Forum Update on Monday, May 27th 2025

Using Mocks with Networking

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 2.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mstoth
    wrote on 1 Aug 2017, 13:13 last edited by mstoth 8 Jan 2017, 13:39
    #1

    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 {
    public:
        MOCK_METHOD0(isConnected,bool());
        MOCK_METHOD0(connectToHostServer,void());
        MOCK_METHOD1(sendMessageToTcpServer,void(char const *));
    };
    
    class MockTcpSocket : public QTcpSocket {
    public:
        MOCK_METHOD1(waitForConnected,bool(int));
    };
    
    TEST(TestMessenger,checksConnect) {
        MockMessenger m;
        ON_CALL(m,isConnected()).WillByDefault(Return(true));
    
        EXPECT_CALL(m,isConnected()).Times(1);
        Communicator::Instance()->connectToTcpServer();
        ASSERT_TRUE(m.isConnected());
    }
    
    TEST(TestMessenger,checksTcp) {
        MockTcpSocket s;
        ON_CALL(s,waitForConnected(5000)).WillByDefault(Return(true));
        EXPECT_CALL(s,waitForConnected(5000)).Times(1);
        ASSERT_TRUE(s.waitForConnected(5000));
    }
    
    
    
    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!
    Michael

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 1 Aug 2017, 21:51 last edited by
      #2

      Hi,

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

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mstoth
        wrote on 10 Aug 2017, 14:44 last edited by mstoth 8 Oct 2017, 14:46
        #3

        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.

        Communicator::Instance.sendMsgToTcpServer("{\"mtype\":\"GIRQ\"}");

        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 {
        public:
            virtual void sendMessageToTcpServer(char const *) = 0;
            virtual void connectToTcpServer() = 0;
            virtual bool isConnected() = 0;
        };
        
        
        class Messenger : public IMessenger
        {
            Q_OBJECT
        public:
            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;
        
        
        private:
            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;
        signals:
            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();
        
        private:
        
        };
        
        typedef Singleton<Messenger> Communicator;
        
        #endif // MESSAGER_H
        
        
        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 10 Aug 2017, 22:16 last edited by
          #4

          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.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mstoth
            wrote on 11 Aug 2017, 12:41 last edited by
            #5

            ok, i'll look into QIODevice, thanks!

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved