簡體   English   中英

在do.net 5 web api項目中,如何在測試方法中獲取singleton服務的實例?

[英]In a dotnet 5 web api project, how do I get the instance of a singleton service in a test method?

我正在集成測試我的 asp.net 5 web api。 在我的測試方法中,我想獲得對偽造服務實例 a 的引用,以便我可以為我的測試自定義服務的行為。

在應用程序中,服務范圍為 singleton。

//in ConfigureServices in Startup.cs    
services.AddSingleton<IYbNewProjectsService, YbNewProjectsService>();

在我的測試項目中,我在我的 TestFixture class 中設置了我的客戶端和服務器,並保存了對 ServiceProvider 的引用,由 services.BuildServiceProvider() 調用返回給我......

private void SetupClient()
{
    Client = Factory.WithWebHostBuilder(builder =>
    {
        builder.ConfigureTestServices(services =>
        {
            services.Remove<IYbNewProjectsService>();
            services.AddSingleton<IYbNewProjectsService, FakeYbNewProjetsService>();
        });

        builder.ConfigureServices(services =>
        {
            ServiceProvider = services.BuildServiceProvider();
        });
    })
    .CreateClient(new WebApplicationFactoryClientOptions
    {
        AllowAutoRedirect = false
    });
}

我知道它在工作,因為在我的測試中,當我做...

// ServiceProvider is inherited from TestFixture, so it's the same as above.
var fakeYbService = (FakeYbNewProjectsService)ServiceProvider.GetService(typeof(IYbNewProjectsService));
fakeYbService.InjectedResponse = @"[{{""idProjet"":1883557,""dateDApplication"":...
var response = await Client.GetAsync("/api/yb-new-projects");

...我得到了我的偽造服務。 問題是,當我調用Client.GetAsync()時,TestServer 正在使用同一偽造服務的干凈實例,而沒有我的InjectedResponse 這應該是一個 singleton,那么為什么有兩個呢?

您不需要自己設置ServiceProvider ,它在Factory上可用:

// Use this:
Factory.Services.GetService(typeof(IYbNewProjectsService));

// Instead of:
ServiceProvider.GetService(typeof(IYbNewProjectsService));

使用此設置(.NET 5 Razor 頁應用程序 + .NET 5 XUnit 測試項目),它對我來說工作正常:

// In app Startup.ConfigureServices:
services.AddSingleton<ITestService, TestService>();

// Test
[Fact]
public async Task Test1()
{
    var factory = new WebApplicationFactory<Startup>()
        .WithWebHostBuilder(builder =>
        {
            builder.ConfigureTestServices(services =>
            {
                services.AddSingleton<ITestService, FakeTestService>();
            });
        });

    var svc = factory.Services.GetService<ITestService>();
    svc.Do();

    var client = factory.CreateDefaultClient();

    await client.GetAsync("http://localhost");
}

它調用的端點也獲取ITestService並調用該方法。 在這兩種情況下,我都在FakeTestService中遇到了斷點。

您可以檢查的一件事是Startup.ConfigureServices是否在ConfigureTestServices之前運行? 在我的例子中,它允許我們覆蓋服務。 如果它們以其他順序運行,您的測試服務將被覆蓋。 在這種情況下,您需要在 Startup class 中使用TryAddSingleton

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM