单元测试:静态创建方法

时间:2018-09-08 11:50:07

标签: c++ unit-testing

我想开始为缓冲区类编写一些单元测试,而我在使用静态create方法时有些挣扎。

class MyBuffer
{
public: 
  static MyBuffer* create(int32 bufSize)
  {
     if(!bufSize)
       return nullptr; 

     char* internalBuf = (char*)malloc(bufSize);
     if(nullptr == internalBuf) return nullptr; 

     return new MyBuffer(internalBuf, bufSize);
  }

 public bool write(void* data, int32 dataSize) {...}

private:
 MyBuffer(char* buf, int32 size) : internalBuf(buf), size(bufSize) {}

 char* internalBuf = nullptr; 
 int32 bufSize = 0;
};

//just dummy code
TEST(MyBuffer bufferWithZeroSize)
{ 
   auto buf = MyBuffer::create(0);
   ASSERT_True(nullptr == buf);
}

TEST(MyBuffer writeDataToBuffer)
{
  //arrange
  auto buf = MyBuffer::create(50); 
  ASSERT_NotNull(buf); //is this call needed

  //act
  buf->write(...); 

  //assert 
}

验证MyBuffer创建过程似乎可以。

在第二次测试中,可以确定MyBuffer的创建过程成功吗?否则,我必须在单元测试的“ act”部分中对其进行检查。这对我来说听起来不太合理,因为每个单元测试只想检查一件事。另一方面,我知道malloc调用可能会失败。

如何使用静态创建方法测试对象?有没有有用的测试策略,或者建议重构这些对象?我主要使用静态创建方法,以避免对象的调用者忘记正确初始化对象。因此,这对我来说是一种有效的方法。

2 个答案:

答案 0 :(得分:1)

  

我主要使用静态创建方法,以避免对象的调用者忘记正确初始化对象。

用户无法“忘记”初始化如下所示的MyBuffer实例。

#include <cstddef>

class MyBuffer
{
private:
    std::size_t bufSize;
    char* internalBuf;

public:
    MyBuffer(std::size_t size)
    : bufSize{ size }
      internalBuf{ new char[size] },
    {}

    // + whats missing to satisfy the rule of 5

    bool write(char *data, std::size_t dataSize)
    {
        /* ... */
        return true;
    }
};

注意:出于没有明显原因,请勿使用malloc()。使用std::size_t作为内存中对象的大小。

有关最新评论的更新

#include <cstddef>
#include <stdexcept>
#include <algorithm>

class MyBuffer
{
public:
    static constexpr std::size_t min_size{ 10 };
    static constexpr std::size_t max_size{ 42 };

private:
    std::size_t bufSize;
    char* internalBuf;

public:
    MyBuffer(std::size_t size)
    : bufSize{ size == std::clamp(size, min_size, max_size) ?
               size : throw std::invalid_argument{ "size is out of range!" } },
      internalBuf{ new char[bufSize] }
    {}
};

答案 1 :(得分:0)

我怀疑您不需要首先编写缓冲区类,而可以使用std::vector<char>来代替。通常,您应该尝试避免使用原始内存管理(根本不要编写new / delete / malloc / free(尤其是delete / free))。

对于单元测试问题,是的,可以进行一些设置以便达到您的实际测试(或多个测试)。当您在测试之间重用安装程序时,它通常称为夹具。我认为在同一测试中测试几件事情并不罕见。有时,测试本身的性能也可能是一件事情,然后,如果设置成本很高,则可以测试更多的事情。