I use minimal hosting API using .NET Core 7 with "flat" Program.cs such as:
var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
var services = builder.Services;
services.AddControllers();
services.AddSingleton<IBla, Bla>();
services.AddSingleton<IFoo, Foo>();
// etc..
var app = builder.Build();
// etc..
app.Run();
public partial class Program { }
IFoo is injected in Bla constructor. Then in a Nunit test (along with FakeItEasy), there is:
var application = new WebApplicationFactory<Program>().WithWebHostBuilder(builder => {
builder.UseEnvironment("Development")
.ConfigureTestServices(services => {
// register the service being tested
// Do I need it as it's already in Program.cs?
services.AddScoped<IBla, Bla>();
// WORKS
services.AddScoped<IFoo, FooFake>();
// DOES NOT WORK
//var foo = new Fake<IFoo>();
//foo.CallsTo(x => x.GetAsync(A<string>.Ignored))
// .Returns(111);
//services.AddSingleton(foo);
});
});
var client = application.CreateClient();
var response = await client.GetAsync("/api/car/21");
When I use mocked service, the real implementation is invoked (the one from Program.cs) When I use Fake service it works fine but that's not what I want.
Thank you in advance for your help!
Do I need it as it's already in Program.cs?
No, you don't if the registered implementation satisfies you
WORKS
Yes, this will work, build-in DI uses the last registered implementation, with a caveat - if you will resolve IEnumerable<IFoo>
somewhere it will contain the "unwanted" implementation too. Usual approach to mitigate that is to clean up the service collection before adding new registration:
services.RemoveAll(typeof(IFoo));
DOES NOT WORK
Because services.AddSingleton(foo);
will register service of type Fake<IFoo>
. Not sure what Fake
is but possibly you want something like services.AddSingleton<IFoo>(foo);
or services.AddSingleton<IFoo>(foo.SomethingWhatReturnsFoo);
depending on how this particular fake/mock library works.