I'm integration testing my asp.net 5 web apis. 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.
In the app, the service is scoped as 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...
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
. This is meant to be a singleton, so why are there two of them?
You don't need to setup a ServiceProvider
yourself, it's available on the 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):
// 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. In both cases I hit the breakpoint in the FakeTestService
.
One thing you could check is that does the Startup.ConfigureServices
run before the 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.