如何使用私有构造函数对类进行单元测试?

Posted

技术标签:

【中文标题】如何使用私有构造函数对类进行单元测试?【英文标题】:How to unit test a class with private constructor? 【发布时间】:2018-08-17 17:46:49 【问题描述】:

我有一个班级 Foo。我只想让 Bar 创建它,所以我将它的构造函数设为私有并让 Bar 成为它的朋友。但是现在我如何对 Foo 的公共方法(例如 getValue)进行单元测试?我没有办法在单元测试文件中创建它的实例。

class Foo final

public:
    int getValue();
private:
    friend class Bar;
    Foo(int value);
;

class Bar

protected:
    Foo createFoo(int value);
;

【问题讨论】:

也许你需要稍微修改一下你对“单位”的定义。要点是,由于您的类只能通过工厂创建,因此它的构造函数不是接口的一部分。因此,这两个类一起形成了一个单元,而不是单独的单元。 如果你使用 gcc 或 clang,你可以使用-fno-access-control 编译你的单元测试,这样你就可以访问私有成员 【参考方案1】:

您可以为单元测试添加额外的朋友类

class Foo final

public:
    int getValue();
private:
    friend class Bar;
    friend class UnitTests; // Here
    Foo(int value);
;

class UnitTests 
public:
     bool constructor_ok()  Foo test_instance(42); ... 
;

【讨论】:

【参考方案2】:

有两种可能的方法。

首先是单元测试利用Bar实例化Foo,然后对Foo的公共成员进行测试。这意味着您的单元测试结合使用BarFoo 的工作,这是适当的,因为(大概)您将Foos 构造函数设为私有和Bar 成为朋友的意图是为了防止Foo 被使用分别地。根据Bar 的定义方式,您可能需要单独的单元测试来单独执行Bar(即独立于Foo)。

第二种选择是将另一个类声明为friend,然后使用该类在Foo 上独立于Bar 实现测试。

就个人而言,我更喜欢第一个选项。使用第二个选项,Bar 的工作可能与 Foos 单元测试的工作不同步(反之亦然) - 这意味着第二个选项将引入通过单元测试的可能性,然后在BarFoo 的错误交互下释放您的程序。

【讨论】:

以上是关于如何使用私有构造函数对类进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Typescript中对私有方法进行单元测试

如何对不可变类构造函数进行单元测试?

java java中的单元测试私有构造函数

如何在 Swift 中对私有或内部函数进行单元测试?

golang:如何对私有函数进行单元测试

golang:如何对私有函数进行单元测试