简体   繁体   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?

I'm integration testing my asp.net 5 web apis.我正在集成测试我的 asp.net 5 web api。 In my test methods I want to get a reference to the instance a of faked service so I can customise the service's behaviour for my tests.在我的测试方法中,我想获得对伪造服务实例 a 的引用,以便我可以为我的测试自定义服务的行为。

In the app, the service is scoped as singleton.在应用程序中,服务范围为 singleton。

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

In my test project, I set up my client and server in my TestFixture class, and save a reference to the ServiceProvider, returned to me by the services.BuildServiceProvider() call...在我的测试项目中,我在我的 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
    });
}

I know it's working, because in my tests, when I do...我知道它在工作,因为在我的测试中,当我做...

// 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");

...I get my faked service. ...我得到了我的伪造服务。 Trouble is, when I call Client.GetAsync() , the TestServer is using a clean instance of the same faked service, without my InjectedResponse .问题是,当我调用Client.GetAsync()时,TestServer 正在使用同一伪造服务的干净实例,而没有我的InjectedResponse This is meant to be a singleton, so why are there two of them?这应该是一个 singleton,那么为什么有两个呢?

You don't need to setup a ServiceProvider yourself, it's available on the Factory :您不需要自己设置ServiceProvider ,它在Factory上可用:

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

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

It works correctly for me with this setup (.NET 5 Razor pages app + .NET 5 XUnit test project):使用此设置(.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");
}

The endpoint it calls also gets the ITestService and calls the method.它调用的端点也获取ITestService并调用该方法。 In both cases I hit the breakpoint in the FakeTestService .在这两种情况下,我都在FakeTestService中遇到了断点。

One thing you could check is that does the Startup.ConfigureServices run before the ConfigureTestServices ?您可以检查的一件事是Startup.ConfigureServices是否在ConfigureTestServices之前运行? In my case it does which allows us to overwrite the service.在我的例子中,它允许我们覆盖服务。 If they were to run in the other order, your test service would get overwritten.如果它们以其他顺序运行,您的测试服务将被覆盖。 In this case you would need to use TryAddSingleton instead in your Startup class.在这种情况下,您需要在 Startup class 中使用TryAddSingleton

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Web API中使用Dictionary作为带有GET方法的参数? - How do I use Dictionary as a parameter with the GET method in Web API? Dotnet Web API 项目自动生成控制器的 POST 方法问题 - Issue with POST method of Auto generated Controller for Dotnet Web API project 在启动时获取单例服务的实例 - Get instance of singleton service in startup ASMX Web服务方法单例 - ASMX Web Service Method Singleton 如何在返回IHttpActionResult时对web api动作方法进行单元测试? - How do I unit test web api action method when it returns IHttpActionResult? DotNet Core,如何使用自定义 model 绑定对 Controller 操作方法进行单元测试 - DotNet Core, How do I unit test a Controller Action method with a custom model binding 如何列出 Dotnet 库的 API? - How do I list the API of a Dotnet library? 如何编写Web Api单元测试,我应该从UserManager获取信息 - How do I write Web Api unit test which I should get info from the UserManager 我如何从单例服务中调用方法以在整个应用程序生命周期中运行 - How do i call a method from a singleton service to run throughout the application lifetime 如何在C#中测试与未知Web服务的连接? - How do I test connectivity to an unknown web service in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM