如何在 .net6 中使用 WebApplicationFactory(没有可说的入口点)
Posted
技术标签:
【中文标题】如何在 .net6 中使用 WebApplicationFactory(没有可说的入口点)【英文标题】:How to use WebApplicationFactory in .net6 (without speakable entry point) 【发布时间】:2021-09-04 18:55:15 【问题描述】:在 ASP.NET Core 6 中,默认模板将所有内容从 Sturtup.cs
移动到 Program.cs
,并使用 Program.cs 中的***语句,因此不再有(可说的)Program
类 ether。
这看起来很棒,但现在,我需要测试所有这些。 WebApplicationFactory<T>
仍然希望我通过入口点类,但我不能这样做(因为它的名字现在无法说出)。
在 ASP.NET Core 6 中如何配置集成测试?
【问题讨论】:
您需要将服务设置提取到扩展方法中,然后在测试项目中创建一个启动类并调用这些扩展方法。现在您可以使用WebApplicationFactory<TStartup>
,而无需在应用项目中使用。
@abdusco 听起来像个黑客。这样我就不会在Program.cs
中看到我的大部分配置(我认为这是将Startup
移动到那里的意图)。您的建议是或多或少地创建一个新的Sturtup
。但是感谢您的解决方法,这至少是使其正常工作的某种方式。
@abdusco 等等,但我仍然需要提供一些 TStartup
,不是吗?
您可以随时将扩展类/启动类放在 Program.cs 中。不管不引入抽象,如何指定 Program.cs 中的哪些行属于应用程序配置?好吧,您将应用程序设置提取到一个类中并为其命名,稍后您可以在测试项目中引用它,这正是 Startup 类的用途。最小化 API 很酷,但它的命令性使得目前有些事情变得困难。
【参考方案1】:
问题已在 ASP.NET Core RC1 上解决,但截至目前(2021 年 9 月 20 日)文档不完整。
编译器在后台生成一个Program
类,可以与WebApplicationFactory<>
一起使用。该类不是公开的,所以应该使用InternalsVisibleTo
项目设置。
Damien Edwards' Minimal API sample 使用the latest nightly bits。测试网络应用程序类声明为:
internal class PlaygroundApplication : WebApplicationFactory<Program>
private readonly string _environment;
public PlaygroundApplication(string environment = "Development")
_environment = environment;
protected override IHost CreateHost(IHostBuilder builder)
...
在应用程序项目文件中,InternalsVisibleTo
用于使Program
类对测试项目可见:
<ItemGroup>
<InternalsVisibleTo Include="MinimalApiPlayground.Tests" />
</ItemGroup>
RC1 功能齐全,从以前的主要版本来看,它可能是第一个拥有Go Live
许可证的版本,这意味着它在生产中得到支持。
【讨论】:
感谢您的提示,这确实有效,但是将InternalsVisibleTo
添加到 api 项目中:github.com/dotnet/AspNetCore.Docs/issues/… 您能否将其添加到答案中?花了一些时间弄清楚为什么使用 Program
会失败。
@МаксимКошевой 谢谢,我添加了这个【参考方案2】:
请注意,如果您尝试使用 xUnit 及其IClassFixture<T>
模式,如果您只使用 InternalsVisibleTo 方法,您将遇到问题。具体来说,你会得到这样的东西:
“不一致的可访问性:基类 WebApplicationFactory<Program>
的可访问性低于类 CustomWebApplicationFactory
。”
当然,您可以通过将CustomWebApplicationFactory
设为内部来解决此问题,但它只会移动问题,因为现在您的单元测试类将给出相同的错误。当您尝试在那里更改它时,您会发现 xUnit 要求测试具有公共构造函数(不是内部构造函数)并且您将被阻止。
避免所有这些并允许您仍然使用IClassFixture<Program>
的解决方案是将Program
类公开。您显然可以通过摆脱神奇的无类版本 Program.cs 来做到这一点,但如果您不想完全更改该文件,您可以添加以下行:
public partial class Program // so you can reference it from tests
当然,一旦公开,您就可以在测试项目中使用它,一切正常。
顺便说一句,您通常更喜欢使用 IClassFixture 的原因是它允许您在测试类构造函数中设置一次 WebApplicationFactory,并从中获取一个 HttpClient
实例,您可以将其存储为场地。这允许您的所有测试更短,因为它们只需要引用客户端实例,而不是工厂。
例子:
public class HomePage_Get : IClassFixture<CustomWebApplicationFactory>
private readonly HttpClient _client = new HttpClient();
public HomePage_Get(CustomWebApplicationFactory factory)
_client = factory.CreateClient();
[Fact]
public async Task IncludesWelcome()
HttpResponseMessage response = await _client.GetAsync("/");
response.EnsureSuccessStatusCode();
string stringResponse = await response.Content.ReadAsStringAsync();
Assert.Contains("Welcome.", stringResponse);
最后请注意,在我们讨论该问题后,Damian Edwards' MinimalAPIPlayground 已更新为使用此方法。看到这个commit
【讨论】:
听起来像是一种解决方法.. 哦,确实是这样。public partial class Program
为我工作,我不必使用InternalsVisibleTo
公开内部类型。以下是提到使用WebApplicationFactory
进行测试但没有Startup
类的文档的链接:docs.microsoft.com/en-us/aspnet/core/test/…【参考方案3】:
我试过了
<InternalsVisibleTo Include="MinimalApiPlayground.Tests" />
但没有雪茄!将其删除并在 program.cs 中添加了一个部分类
#pragma warning disable CA1050 // Declare types in namespaces
public partial class Program
#pragma warning restore CA1050 // Declare types in namespaces
效果惊人。
【讨论】:
这很奇怪InternalsVisibleTo
为我工作(并继续在 .Net 6 rc2 中工作)。你的Program
类是public
,所以这个问题可能是你错误地添加了InternalsVisibleTo
。也许您的测试项目的名称不是MinimalApiPlayground.Tests
嗨@maxc137,我确实更改了名称,但是,我使用了“ABC”中的名称而不是.Tests(大概是一个命名空间),有趣的是我会再试一次,我不是当然,但我认为我更喜欢在启动时,因为现在更容易记住两次被这个抓住了!以上是关于如何在 .net6 中使用 WebApplicationFactory(没有可说的入口点)的主要内容,如果未能解决你的问题,请参考以下文章