好吧,我刚刚收到一个作业,我必须对具有私有构造函数的类执行单元测试。
现在,当所有方法都是非静态时,我该如何在不初始化类的情况下进行单元测试。
有什么方法可以对具有私有构造函数的类进行单元测试(无需反射)?
如果您无法将类公开,您仍然可以通过以下方式创建它的实例来轻松测试它:
var anInstance = (YourPrivateClass)Activator.CreateInstance(typeof(YourPrivateClass), true);
这将为您提供一个类的实例,然后您可以填充该实例。
另一个有用的测试位是,如果您有内部方法(非私有),您可以通过使内部方法对您的测试类可见来访问它们。您可以使用内部方法在类的 assemblyinfo.cs 中添加这一行:
[assembly: InternalsVisibleTo("YourSolution.Tests")]
如果这个类有一个私有构造函数,是否可以公开使用?如果没有,最好不要对其进行单元测试。如果是这种情况,公共代码应该通过调用它来测试该代码。
单元测试是为了测试公众使用的内容 - 例如通过应用程序层之间的接口代码。接受一个输入,我想要这个输出。这确实是单元测试的意义所在。单元测试不关心实际方法中的内容。只要它返回你想要的,执行你想要的动作,你就通过了。
您应该通过公共 API 进行测试——必须有某种方式来实例化和使用您想要测试的类。
通常编写和运行单元测试是为了确保代码符合其设计并按预期运行。
创建一个无法在其上创建实例(即仅私有构造函数)的
non-static
类,可能永远不会有用,换句话说,它永远不会 Unit Testable
。
为了可进行单元测试:
它可能是一个单例,并且您不想要该类的公共构造函数。 用以下内容装饰构造函数: [从代码覆盖范围中排除]
我意识到OP(Win Coder)特别要求一个在他们的问题中不使用反射的解决方案。然而,Google 将此作为有关在 C# 中测试私有构造函数的一般问题的最佳结果。
所以,如果您已经到达这里并且可以使用反射。这是一个解决方案。
在此示例中,我使用私有构造函数创建
MyClass
的实例,该构造函数按顺序接受三个(且仅三个)类型为 int,
string,
和 string
的参数。参数的类型、顺序和数量需要匹配。
var constructor = typeof(MyClass).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
[typeof(int), typeof(string), typeof(string)]);
var myObject = constructor?.Invoke([id, name, desc]) as MyClass;
// Run whatever unit tests you need to run on myObject.
对于那些不同意对私有构造函数进行单元测试的人,有一个 Entity Framework Core 用例,其中您的私有构造函数被公开使用。道格拉斯·加斯克尔在对已接受答案的评论中提到了这一点。