Mocking Services in ASP.NET Core Tests with ConfigureTestServices()
Let's say you have the following ASP.NET Core project.
namespace PlaygroundApi
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IPaymentService>(x => new StripePaymentService());
var app = builder.Build();
app.MapGet("/", (IConfiguration config) =>
{
var projectKey = config.GetValue<string>("ProjectKey");
return $"ProjectKey is: '{projectKey}'";
});
app.Run();
}
}
}
It has a IPaymentService
scoped service injected with a StripePaymentService
implementation.
For the needs of integration testing we want to mock the payment service, and not use the real StripePaymentService
implementation. To do that, we can use the ConfigureTestServices
method extension in the TestServer to override the IPaymentService
implementation with a MockPaymentService
.
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace PlaygroundApi.Tests
{
public class UnitTest1
{
private readonly WebApplicationFactory<PlaygroundApi.Program> _webAppFactory;
public UnitTest1()
{
_webAppFactory = new WebApplicationFactory<PlaygroundApi.Program>()
.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.AddScoped<IPaymentService>(x => new MockPaymentService());
});
});
}
[Fact]
public void Test_payment()
{
using var scope = _webAppFactory.Services.CreateScope();
var paymentService = scope.ServiceProvider.GetRequiredService<IPaymentService>();
// Test proof that the payment service type now is the mock.
Assert.Equal(typeof(MockPaymentService), paymentService.GetType());
}
}
}