单元测试用于进行标准库调用的C++方法的模式

Jos*_*ver 10 c++ unit-testing

我正在编写一个C++类来包装套接字(我知道这里有很好的库 - 我自己开始练习):

class Socket {
public:
  int init(void); // calls socket(2)
  // other stuff we don't care about for the sake of this code sample
};
Run Code Online (Sandbox Code Playgroud)

这个类反过来被其他几个人使用,我知道我可以通过子类化和模拟googlemock进行单元测试.

但我想首先开发这个类测试,目前有点卡住了.我不能在C标准库上使用googlemock(也就是说socket.h,在这种情况下),因为它不是C++类.我可以围绕我需要的C标准库函数创建一个瘦C++包装类,例如

class LibcWrapper {
public:
   static int socket(int domain, int type, int protocol);
   static int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
   static int listen(int sockfd, int backlog);
   static int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
   static ssize_t write(int fd, const void *buf, size_t count);
   static int close(int fd);
};
Run Code Online (Sandbox Code Playgroud)

现在我可以模拟那个和单元测试我的Socket类(现在可能需要重命名Network或者其他一些).LibcWrapper对于其他类也可以派上用场,并且本身不需要进行单元测试,因为它只提供了一堆类方法.

这开始对我来说听起来不错.我是否已经回答了我自己的问题,或者是否存在用于在C++中进行此类开发的测试的标准模式?

Dou*_* T. 5

我可能会通过使用套接字接口(即基类)并实现该基类的测试版本来模拟它。

您可以通过多种方式执行此操作,例如,最简单的方法是根据 C++ 接口指定整个套接字 API。

   class ISocket
   {
   public:
        virtual int socket(int domain, int type, int protocol) = 0;
        virtual int bind(int sockfd...) = 0;
        // listen, accept, write, etc            
   };
Run Code Online (Sandbox Code Playgroud)

然后提供通过 BSD 套接字库工作的具体实现

   class CBsdSocketLib : public ISocket
   {
   public:
       // yadda, same stuff but actually call the BSD socket interface
   };


   class CTestSocketLib : public ISocket
   {
   public:
       // simulate the socket library
   };
Run Code Online (Sandbox Code Playgroud)

通过对界面进行编码,您可以创建您的测试版本来做任何您喜欢的事情。

但是,我们可以清楚地看到,这第一关相当奇怪。我们包装了一个完整的库,从它描述对象的意义上说,它并不是真正的类。

您更愿意考虑插座和制造插座的方法。这将更加面向对象。按照这些思路,我将上述功能分为两类。

   // responsible for socket creation/construction
   class ISocketFactory
   {
        virtual ISocket* createSocket(...) = 0; // perform socket() and maybe bind()
   };

   // a socket
   class ISocket
   {
         // pure virtual recv, send, listen, close, etc
   };
Run Code Online (Sandbox Code Playgroud)

现场使用:

   class CBsdSocketFactory : public ISocketFactory
   {
      ...
   };

   class CBsdSocket : public ISocket
   { 
      ...
   };
Run Code Online (Sandbox Code Playgroud)

用于检测:

   class CTestSocketFactory : public ISocketFactory
   {
   };

   class CTestSocket : public ISocket
   {
   };
Run Code Online (Sandbox Code Playgroud)

并将 BSD 库调用分成两个不同的类,它们有自己的职责。