关于.net:进行单元测试时的C#“内部”访问修饰符

C# “internal” access modifier when doing unit testing

我是一个新的单元测试人员,我想知道是否应该开始使用更多的"内部"访问修饰符。我知道,如果我们使用"internal"并设置程序集变量"internalsVisibleTo",我们可以测试不希望从测试项目中声明为public的函数。这让我觉得我应该总是使用"内部"的,因为至少每个项目(应该?)拥有自己的测试项目。你们能告诉我为什么我不能这样做吗?我什么时候应该使用"private"?


需要测试内部类,并且有assemby属性:

1
2
3
using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo("MyTests")]

将其添加到项目信息文件中,例如Properties\AssemblyInfo.cs


如果要测试私有方法,请查看PrivateObjectPrivateType命名空间中的Microsoft.VisualStudio.TestTools.UnitTesting。它们在必要的反射代码周围提供易于使用的包装器。

Docs:私有类型,私有对象


默认情况下保持使用私密。如果一个成员不应该暴露在该类型之外,那么它不应该暴露在该类型之外,甚至是在同一个项目中。这样可以使事情更安全、更整洁——当你使用这个对象时,你应该能够使用的方法就更清楚了。

尽管如此,我认为有时出于测试目的,将自然私有的方法作为内部方法是合理的。我更喜欢使用反射,这是重构不友好。

要考虑的一件事可能是"fortest"后缀:

1
2
3
4
5
6
7
8
9
internal void DoThisForTest(string name)
{
    DoThis(name);
}

private void DoThis(string name)
{
    // Real implementation
}

然后,当您在同一个项目中使用这个类时,很明显(现在和将来)您不应该真正使用这个方法——它只是用于测试目的。这有点老土,不是我自己做的,但至少值得考虑。


您也可以使用private,并且可以使用反射调用private方法。如果您使用的是Visual Studio团队套件,它有一些很好的功能,可以生成一个代理来调用您的私有方法。下面是一篇代码项目文章,演示如何自己完成单元测试私有和受保护方法的工作:

http://www.codeproject.com/kb/cs/testnopublicmembers.aspx

关于应该使用哪个访问修饰符,我的一般经验法则是从private开始,并根据需要升级。通过这种方式,您将只公开真正需要的类的内部细节,这有助于保持实现细节的隐藏,因为它们应该是隐藏的。


添加到Eric的答案中,您还可以在csprojDirectory.Build.props文件中通过添加:

1
2
3
4
5
<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
      <_Parameter1>$(MSBuildProjectName).Test</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

请参阅:https://stackoverflow.com/a/49978185/1678053