如何测试内部类库?

我想编写一个类库,它为我创建了一个复杂的对象,但只应该尽可能少地公开。我希望它被包含到其他项目中,在那里我只有一个对这个库的调用,例如返回一个内部创建类的对象。我不想让其他人显式地创建这些对象,但是我仍然想为这个类库创建一个测试项目。

例如:

var result = Manager.Instance.Create(definition)

这应该是对类库的唯一访问权限。

基于定义参数,它使用不同的子类来创建请求的实例,并相应地设置它的属性。因此,我想通过测试来保证整个创造过程运行良好。但是由于我也不想公开 result 对象的很少的内部属性,所以我不能仅仅使用这个公共访问方法进行测试,因为我没有任何可以断言的属性。

我知道你不应该测试内部机制,这是典型的糟糕设计,我也通过 这篇文章阅读,但是有没有可能有任何方法来创建一个库加单元测试项目,也许以后限制访问这个类?用包装纸什么的吗?

34679 次浏览

进去。NET 中,可以使用类库中的 InternalsVisibleToAttribute使内部类型对单元测试项目可见。

这样,您可以将类保留在内部,同时仍然可以从您提供访问权限的其他程序集中使用它。

你可以这样使用:

[assembly:InternalsVisibleTo("NameOfYourUnitTestProject")]

对于最新的 csproj 2017格式化项目,如果您的项目没有 AssemblyInfo.cs文件,您可以添加以下设置:

  <ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(MSBuildProjectName).Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

您还可以使用其他变量来替换 MSBuildProjectName,例如 AssemblyName,或者直接使用 unittest 项目名称。

可以通过添加 InternalsVisibleTo来检查 obj 文件夹(obj\Debug\netstandard2.0)中的 ProjectName.AssemblyInfo.cs是否已经更新。

在我的例子中(. NET5应用程序) ,我需要两个 csproj 条目:

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>MyAppName.UnitTests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

和内部可见性归因于我的类,为了这个工作:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
namespace MyAppName.Api.Something...