资源管理类中的单元测试私有方法(C++)

Bil*_*eal 6 c++ unit-testing raii boost-test

我之前用另一个名字问了这个问题,但删除了它,因为我没有很好地解释它.

假设我有一个管理文件的类.假设此类将文件视为具有特定文件格式,并包含对此文件执行操作的方法:

class Foo {
    std::wstring fileName_;
public:
    Foo(const std::wstring& fileName) : fileName_(fileName)
    {
        //Construct a Foo here.
    };
    int getChecksum()
    {
        //Open the file and read some part of it

        //Long method to figure out what checksum it is.

        //Return the checksum.
    }
};
Run Code Online (Sandbox Code Playgroud)

假设我希望能够对计算校验和的这个类的部分进行单元测试.单元测试加载到文件中的类的部分是不切实际的,因为要测试getChecksum()方法的每个部分,我可能需要构建40或50个文件!

现在假设我想在类中的其他地方重用校验和方法.我提取方法,使它现在看起来像这样:

class Foo {
    std::wstring fileName_;
    static int calculateChecksum(const std::vector<unsigned char> &fileBytes)
    {
        //Long method to figure out what checksum it is.
    }
public:
    Foo(const std::wstring& fileName) : fileName_(fileName)
    {
        //Construct a Foo here.
    };
    int getChecksum()
    {
        //Open the file and read some part of it

        return calculateChecksum( something );
    }
    void modifyThisFileSomehow()
    {
        //Perform modification

        int newChecksum = calculateChecksum( something );

        //Apply the newChecksum to the file
    }
};
Run Code Online (Sandbox Code Playgroud)

现在我想对该calculateChecksum()方法进行单元测试,因为它易于测试和复杂,而且我不关心单元测试,getChecksum()因为它很简单且很难测试.但我无法calculateChecksum()直接测试,因为它是private.

有谁知道这个问题的解决方案?

Dav*_*ter 2

基本上,听起来您想要一个模拟来使单元测试更加可行。使类可独立于对象层次结构和外部依赖项进行单元测试的方法是通过依赖项注入。创建一个类“FooFileReader”,如下所示:

class FooFileReader
{
public:
   virtual std::ostream& GetFileStream() = 0;
};
Run Code Online (Sandbox Code Playgroud)

进行两种实现,一种打开文件并将其公开为流(或者字节数组,如果这是您真正需要的)。另一种是模拟对象,它仅返回旨在强调您的算法的测试数据。

现在,使 foo 构造函数具有以下签名:

Foo(FooFileReader* pReader)
Run Code Online (Sandbox Code Playgroud)

现在,您可以通过传递模拟对象来构造 foo 进行单元测试,或者使用打开文件的实现通过真实文件构造它。在工厂中封装“真正的”Foo 的构建,使客户更容易获得正确的实现。

通过使用这种方法,没有理由不对“int getChecksum()”进行测试,因为它的实现现在将使用模拟对象。