使用InternalsVisibleTo的ASP.NET Core WebApplicationFactory在xunit中不起作用

Max*_*yák 3 c# testing xunit asp.net-core dotnet-test

我最初在 asp.net 文档上发布了一个问题,并在此处引用

由于删除了公共 Startup.cs,从 NET5 迁移到 NET6 破坏了使用 WebApplicationFactory 的大量测试。另一种选择是转向程序,该程序在新模板出现之前一直有效。在新模板中没有公共类程序,因此我们需要添加一个公共部分类 Program {}

我正在查看文档,他们提供了一个使用 InternalsVisibleTo 的新解决方案,恕我直言,它更好,因为它不会仅出于测试目的而更改代码。

然而,这会导致这样的代码

public class UnitTest1 : IClassFixture<WebApplicationFactory<Program>>
{
  public UnitTest1(WebApplicationFactory<Program> applicationFactory)
  {
    
  }
}
Run Code Online (Sandbox Code Playgroud)

然而问题是程序是内部的,这会触发 CS0051:

UnitTest1.cs(8, 12):[CS0051] 可访问性不一致:参数类型“WebApplicationFactory”比方法“UnitTest1.UnitTest1(WebApplicationFactory)”更难访问

问题是 xunit 要求它的类/构造函数是公共的。

那么有人设法在没有公众部分的情况下让这项工作正常进行吗?

gld*_*ael 6

如果您只想访问internal Program测试项目中自动生成的类,[InternalsVisibleTo]那么可以。

\n
<ItemGroup>\n  <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">\n    <_Parameter1>TestProject1</_Parameter1>\n  </AssemblyAttribute>\n</ItemGroup>\n
Run Code Online (Sandbox Code Playgroud)\n

但是,您尝试使用类型internal作为类型的类型参数public,并期望该public<internal>类型可以public访问。

\n

想象一下有 3 个程序集的场景:ABC
\nA定义internalInternalImpl并已[InternalsVisibleTo("B")]设置,
\nB定义public类型如下:

\n
public class Container\n{\n   public AnotherPublicType<InternalImpl> AnIllegalPublicProperty { get; }\n   // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在上面的示例中,AnIllegalPublicProperty是非法的,因为尽管程序集B可以访问类型,但该类型仍然是内部类型,程序集(或任何其他程序集)InternalImpl无法访问该类型。C

\n

事实上,虽然AnotherPublicType是一个公共类,但 C# 不允许比内部类具有更高的可访问性,因为允许的最高可访问性是类型 ( ) 及其类型参数 ( )AnotherPublicType<InternalImpl>的最低可访问性。将该属性更改为以下内容将起作用:AnotherPublicTypeInternalImpl

\n
public class Container\n{\n   internal AnotherPublicType<InternalImpl> AnIllegalPublicProperty { get; }\n   // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

有关更多信息,请检查规范 \xc2\xa77.5.3 可访问性域

\n
\n

构造类型 T<A1, ..., Ae> 的可访问域是未绑定泛型类型 T 的可访问域与类型参数 A1, ..., Ae 的可访问域的交集。

\n
\n

要回答您的问题,要么WebApplicationFactory必须制作internal(与IClassFixture一起UnitTest1),要么Program必须制作public

\n

我相信 xunit 需要公开测试。
\n因此,您唯一的选择是将以下内容添加到文件末尾Program.cs

\n
#pragma warning disable CA1050 // Declare types in namespaces\npublic partial class Program { }\n#pragma warning restore CA1050 // Declare types in namespaces\n
Run Code Online (Sandbox Code Playgroud)\n