代码之家  ›  专栏  ›  技术社区  ›  Joe

如何对BSD套接字进行单元测试[关闭]

  •  5
  • Joe  · 技术社区  · 8 年前

    我正在用BSD套接字在Ubuntu中编写一个基于服务器/客户端的C++应用程序。我使用谷歌C++测试框架作为我的单元测试框架。

    我想知道是否有一种方法可以在我的单元测试中创建一个服务器和客户机,这样我就可以测试服务器的侦听/接受,以及双方的发送/接收。

    问题是,如果我要测试服务器的套接字接受(在监听端口之后),那么在这个测试中如何让一些客户端连接到它?我可以使用多线程让客户端连接到同一个测试中的服务器吗 TEST() (或 TEST_F() )范围?

    我可以编写一个客户端并手动连接到被测试的服务器,但这无法实现自动化单元测试的目的。

    我读了一些关于Google Mock的文章,它看起来更像是对我的一次理智检查(查看调用了哪些函数、调用了多少次、返回了什么等等)。

    请帮忙,谢谢。

    1 回复  |  直到 8 年前
        1
  •  7
  •   Bartosz Przybylski    8 年前

    好,让我们从创建网络套接字的抽象开始。我们需要它来模拟对系统函数的调用。从以下内容开始:

    class Socket {
    public:
        virtual bool connect(const struct sockaddr *address, socklen_t address_len) = 0;
        virtual Socket* accept(struct sockaddr *restrict address, socklen_t *restrict address_len) = 0;
        /* more functions */
    }
    

    上面的代码并没有抽象很多东西及其与unix类的绑定,因为它使用 sockaddr socklen_t 您还应该为这两种类型创建抽象,使其具有独立于平台的代码,但这取决于您的设计。

    不需要创建一个具体的TCP/UDP类,以便在实际应用程序中使用它。

    class TCPSocket : public Socket { 
    public:
        TCPSocket() {
            socket_ = socket(PF_INET, SOCK_STREAM, 0);
            if (socket_ == -1) {
                /* handle errors */
            } 
        }
        TCPSocket(int sock) : socket_(sock) {}
        bool connect(const struct sockaddr *address, socklen_t address_len) override {
            return connect(socket_, address, address_len) == 0;
        }
        Socket* accept(struct sockaddr *restrict address, socklen_t *restrict address_len) override {
            int s = accept(socket_, address, address_len);
            if (s == -1) {
                /* handle errors */
            }
            return new TCPSocket(s);
        }
    private:
        int socket_;
    } 
    

    呸:)让我们继续上课。

    让我们假设您的类被命名为 A 并有测试方法 method . 你的课应该 Socket* 在构造函数中,或 方法 应该采取 插座* 作为参数。然后在测试代码中,您可以指定一个mock。

    class MockSock : public Socket {
    public:        
        MOCK_METHOD2(connect, bool(const struct sockaddr*, socklen_t));
        MOCK_METHOD2(accept, Socket*(struct sockaddr*, socklen_t*));
    }
    

    然后实例化MockSock并将其传递给 A. 方法 适当地 EXPECT_CALL 价值观