Answers:
内部类需要测试,并且有一个assemby属性:
using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("MyTests")]
将此添加到项目信息文件,例如Properties\AssemblyInfo.cs
。
private
,但是太多的private
事情很可能指向一个internal
难以提取的类。TDD还是没有TDD,我宁愿拥有更多测试大量代码的测试,而不是拥有很少数量执行相同数量代码的测试。避免测试internal
东西并不能完全帮助获得良好的比率。
#if DEBUG
,#endif
块将启用该选项仅在调试版本。
如果要测试私有方法,请查看PrivateObject
和PrivateType
在Microsoft.VisualStudio.TestTools.UnitTesting
命名空间中。它们为必要的反射代码提供了易于使用的包装器。
对于VS2017和2019,您可以通过下载MSTest.TestFramework nuget找到这些
除Eric的答案外,您还可以在csproj
文件中进行配置:
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>MyTests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
或者,如果每个要测试的项目都有一个测试项目,则可以在Directory.Build.props
文件中执行以下操作:
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(MSBuildProjectName).Test</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
参见:https : //stackoverflow.com/a/49978185/1678053
示例:https : //github.com/gldraphael/evlog/blob/master/Directory.Build.props#L5-L12
默认情况下继续使用私有。如果成员不应该暴露于该类型之外,就不应暴露于该类型之外,甚至不暴露于同一项目内。这样可以使事情更安全,更整洁-使用对象时,您可以使用的方法更加清楚。
话虽如此,我认为有时出于测试目的将内部私有方法设为内部是合理的。我更喜欢使用反射,它是重构不友好的。
要考虑的一件事可能是“ ForTest”后缀:
internal void DoThisForTest(string name)
{
DoThis(name);
}
private void DoThis(string name)
{
// Real implementation
}
然后,当您在同一个项目中使用该类时,很明显(现在和将来)您实际上不应该使用此方法-它仅用于测试目的。这有点棘手,不是我自己做的事,但这至少值得考虑。
ForTest
方法,但是我总是觉得它很丑陋(添加的代码在生产业务逻辑方面没有任何实际价值)。通常,我发现我不得不使用该方法,因为该设计有点不幸(即必须在测试之间重置单例实例)
ForTest
是明显错误的,而如果你只是使该方法内部它看起来像它的优良使用。
您也可以使用私有方法,并且可以通过反射调用私有方法。如果您使用的是Visual Studio Team Suite,它将具有一些不错的功能,它将生成一个代理来为您调用私有方法。这是一个代码项目文章,该文章演示了如何自己完成单元测试私有和受保护方法的工作:
http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx
关于应该使用哪种访问修饰符,我的一般经验法则是从private开始,然后根据需要进行升级。这样,您将仅暴露真正需要的类的内部细节,并且有助于隐藏实现细节(应将其隐藏)。
我正在使用Dotnet 3.1.101
,对我有用的.csproj
其他功能是:
<PropertyGroup>
<!-- Explicitly generate Assembly Info -->
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>MyProject.Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
希望这可以帮助到那里的人!
System.Diagnostics.Debug.Assert()
在方法内部使用来避免对内部方法进行单元测试的需要。