在我们的核心域模型设计中,我们有一个名为“Category”的类,其构造函数是内部设计的。由于构造函数是内部的,因此在编写单元测试用例时,我将无法创建“类别”对象。
所以我的问题是,将构造函数公开以使“类别”类可测试是最佳做法吗?或者我不应该测试“类别”,而应该测试负责创建此对象的类/方法?
的Ta,
Rajeesh
答案 0 :(得分:6)
不要仅为了单元测试而使构造函数公开。如果从设计点开始你决定它应该是内部的,那么就这样离开。测试调用此构造函数的类。
在.NET中,InternalsVisibleToAttribute允许您将内部成员公开给单元测试。
答案 1 :(得分:5)
TDD意味着测试 - 驱动设计,如果您无法测试它,那么构造函数就不能真正“按设计”内部构建。
考虑为什么它是内部的。这将告诉您如何解决该问题。您不应该将构造函数公开以便能够对其进行测试,但应该考虑一种可以轻松创建新实例的设计。
通常,构造函数是内部的,用于保护不变量,但您也可以使用公共构造函数实现相同的目标,该构造函数将所需的输入作为构造函数参数。
public class MyClass
{
private readonly string requiredString;
public MyClass(string requiredString)
{
if (requiredString == null)
{
throw new ArgumentNullException("requiredString");
}
this.requiredString = requiredString;
}
}
注意Guard子句和readonly
关键字的组合如何保护类的不变量。这通常是内部构造函数的一个很好的替代方案。
拥有内部构造函数的另一个原因是当你有一个可能返回多态对象的Factory方法时,但是如果不那么请考虑是否暴露构造函数是一个问题意味着妥协不变量。
TDD的美妙之处在于它迫使我们好好看看任何设计决策,并能够真正证明每一个。考虑将构造函数设置为内部然后修改API以使类型易于创建的理由。
答案 2 :(得分:3)
添加
[assembly: InternalsVisibleTo("UnitTestAssembly")]
到AssemblyInfo.cs。然后UnitTestAssembl.dll
可以调用您的内部方法。更多信息可用here。
答案 3 :(得分:0)
您可以考虑创建一个名为
的静态工厂方法Category *ConstructCategory_ForUnitTest();
您可以使用它来创建对象,只是为了测试它。
从名称中可以明显看出,它不应该在测试环境之外使用,代码审查可以很容易地发现生产等级代码中的“非法”使用。