我试图弄清楚我是否应该开始使用更多的内部访问修饰符。

我知道如果我们使用internal并设置程序集变量InternalsVisibleTo,我们可以测试不想在测试项目中声明为公共的函数。

这让我觉得我应该总是使用internal,因为至少每个项目(应该?)都有自己的测试项目。

为什么不应该这样做呢?什么时候应该使用private?


当前回答

将InternalsVisibleTo.cs文件添加到项目根文件夹中。csproj文件。

InternalsVisibleTo.cs的内容应该如下

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("AssemblyName.WhichNeedAccess.Example.UnitTests")]

其他回答

在。net Core 2.2中,将这一行添加到Program.cs中:

using ...
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("MyAssembly.Unit.Tests")]

namespace
{
...

如果你想测试私有方法,看看Microsoft.VisualStudio.TestTools.UnitTesting命名空间中的PrivateObject和PrivateType。它们为必要的反射代码提供了易于使用的包装器。

文档: PrivateType, PrivateObject

对于VS2017和2019,你可以通过下载MSTest找到这些。TestFramework nuget

从。net 5开始,你也可以在被测试项目的csproj中使用这个语法:

  <ItemGroup>
    <InternalsVisibleTo Include="MyProject.Tests" />
  </ItemGroup>

除了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

对于.NET core,您可以将属性添加到命名空间 [组装:InternalsVisibleTo(“MyUnitTestsAssemblyName”)]。 例如:

using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Applications.ExampleApp.Tests")]
namespace Applications.ExampleApp
 internal sealed class ASampleClass : IDisposable
    {
        private const string ApiVersionPath = @"api/v1/";
        ......
        ......
        ......
        }
    }