Шаблоны для модульного тестирования метода C ++, который выполняет стандартный вызов библиотеки - PullRequest
10 голосов
/ 25 апреля 2011

Я пишу класс C ++, чтобы обернуть сокеты (я знаю, что для этого есть хорошие библиотеки - я использую свои собственные для практики):

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

Этот класс, в свою очередь, используетсядругими, которые, как я знаю, я могу провести модульное тестирование с googlemock путем создания подклассов и насмешек.

Но я хотел бы разработать этот класс сначала для теста , и янемного застрял в настоящее время.Я не могу использовать googlemock в стандартной библиотеке C (т. Е. 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);
};

Теперь я могу поиграть с этим и провести модульное тестирование моего Socket класса (который теперь можетнужно переименовать Network или что-то подобное).LibcWrapper может пригодиться и для других классов, и сам по себе не нуждается в модульном тестировании, поскольку он просто предоставляет набор методов класса.

Это начинает звучать хорошо для меня.Я ответил на свой вопрос или существуют стандартные шаблоны для тест-драйва такого рода разработки в C ++?

Ответы [ 3 ]

4 голосов
/ 25 апреля 2011

Я бы, вероятно, высмеял это, работая через интерфейс сокетов (т.е. базовый класс) и реализуя тестовую версию этого базового класса.

Вы можете сделать это несколькими способами, например, самая простая вещь - указать весь API сокетов в терминах интерфейса C ++.

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

Затем предоставить конкретную работающую реализациючерез библиотеку сокетов 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
   };

Кодируя интерфейс, вы можете создать свою тестовую версию, чтобы делать все что угодно.

Однако мы можем ясно видеть, что этот первый проход довольно странный,Мы обертываем целую библиотеку, она на самом деле не является классом в том смысле, что она описывает объекты.

Вы бы предпочли думать с точки зрения сокетов и способов изготовления сокетов.Это было бы более объектно-ориентированным.Вдоль этих строк я бы разделил описанную выше функциональность на два класса.

   // 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
   };

Для использования в реальном времени:

   class CBsdSocketFactory : public ISocketFactory
   {
      ...
   };

   class CBsdSocket : public ISocket
   { 
      ...
   };

Для тестирования:

   class CTestSocketFactory : public ISocketFactory
   {
   };

   class CTestSocket : public ISocket
   {
   };

И отдельныйбиблиотека BSD вызывает те два разных класса, которые имеют свои обязанности.

2 голосов
/ 25 апреля 2011

Я тоже использовал эту технику. Помните, что Google Mock не поддерживает насмешливые статические функции. В разделе часто задаваемых вопросов объясняется, что вы должны использовать интерфейс с виртуальными методами, которые вы можете переопределить обычным способом Google Mock.

1 голос
/ 25 апреля 2011

Google Mock поваренная книга предлагает нечто подобное в вашем случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...