单元测试领域模型对象

7
在我们的核心领域模型设计中,有一个名为“Category”的类,其构造函数被设计为内部函数。由于构造函数是内部函数,所以在编写单元测试用例时,我将无法创建“Category”对象。
因此,我的问题是,为了使“Category”类可测试,将构造函数设置为公共函数是最佳实践吗?或者我不应该测试“Category”,而应该测试负责创建此对象的类/方法?
谢谢,
Rajeesh

我正在使用C#。我看到“InternalsVisibleToAttribute”的问题是,我们将一个测试用例与实际代码链接起来了。 - Rajeesh
我建议重新措辞标题,以反映该问题是关于具有私有/内部构造函数的类的单元测试。 - andreas buykx
4个回答

6
不要仅为了单元测试而将构造函数设为公共。如果从设计角度决定应该是内部的,请保持这种方式。测试调用此构造函数的类。
在.NET中,有InternalsVisibleToAttribute,可以将内部成员暴露给单元测试。

5
TDD指的是测试驱动开发,其相关原则之一是,如果你无法对构造函数进行测试,那么它就不能真正地“按设计”成为内部函数。
考虑为什么构造函数是内部函数。这将告诉您如何解决问题。您不应该将构造函数设置为public以便进行测试,但是您应该考虑一种设计,使创建新实例变得容易。
通常,构造函数被设置为内部函数以保护不变量,但是您也可以通过公共构造函数接受所需的输入作为构造函数参数来实现相同的目标。
public class MyClass
{
    private readonly string requiredString;

    public MyClass(string requiredString)
    {
        if (requiredString == null)
        {
            throw new ArgumentNullException("requiredString");
        }
        this.requiredString = requiredString;
    }
}

注意到守卫条款和readonly关键字的组合如何保护类的不变量。这通常是内部构造函数的一个很好的替代方案。

另一个需要内部构造函数的原因是当你有一个工厂方法可能返回多态对象时,但同样地,考虑如果暴露构造函数会不会意味着破坏不变量。

TDD的美妙之处在于它迫使我们仔细审视任何设计决策并且能够真正地证明每一个决策都是正确的。考虑将构造函数设为内部并修改API以便易于创建类型的理由。


3

添加

 [assembly: InternalsVisibleTo("UnitTestAssembly")]

将以下代码添加到您的AssemblyInfo.cs文件中。然后UnitTestAssembl.dll就能调用您的内部方法了。更多信息请参见此处


0
你可以考虑创建一个名为静态工厂方法。
Category *ConstructCategory_ForUnitTest();

你可以使用它来创建对象,仅用于测试目的。

从名称上就可以看出,它不应该在测试环境之外使用,在生产级别的代码中,代码审查很容易发现其“非法”使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接