如何对 BSD 套接字进行单元测试

Joe*_*Joe 4 c++ sockets googletest googlemock c++11

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

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

问题是,如果我要为服务器测试套接字接受(在侦听端口后),我如何在此测试中让某些客户端连接到它?我可以使用多线程让客户端连接到相同TEST()(或TEST_F())范围内被测试的服务器吗?

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

我读了一些关于 Google Mock 的内容,它对我来说更像是一种健全性检查(查看哪些函数被调用、调用了多少次、返回了什么,等等)。

请帮忙,谢谢。

小智 5

好的,让我们从为网络套接字创建抽象开始。我们需要它来模拟对系统函数的调用。从这样的事情开始:

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 */
}
Run Code Online (Sandbox Code Playgroud)

上面的代码没有抽象很多东西,它绑定到 unix 类,因为它使用了sockaddrand 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_;
} 
Run Code Online (Sandbox Code Playgroud)

呼:) 让我们继续上课。

让我们假设您的类已命名A并具有测试方法method。你的类要么接受Socket*构造函数,要么method接受Socket*作为参数。然后在您的测试代码中,您可以指定一个模拟。

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

然后只需实例化 MockSock 并将其传递给Amethod使用适当的EXPECT_CALL值。