Reputation: 3968
I am writing a unit test for the following extension method:
public static void AddMyServices(this IServiceCollection services)
{
services.AddScoped<IServiceA, ServiceA>();
}
Here is what I have to confirm the ServiceA
has been injected.
[Test]
public void Should_Resolve_ServiceA() {
// Arrange
var services = new ServiceCollection();
// Act
services.AddMyServices();
var serviceProvider = services.BuildServiceProvider();
var actual = serviceProvider.GetService<IServiceA>();
// Assert
Assert.IsNotNull(actual);
}
The test above did ensure the service has been injected. However, services.AddSingleton
and services.AddTransient
also pass the test.
Is there a solution to get only the scoped injected services so I can ensure it has been injected the correct way?
I am aware that for the simplified example above, I can create a stub for IServiceCollection
and check the ReceivedCalls
on the stub method. However, I am trying to avoid doing that because I have a lot of AddScope
statements in my real extension method and part of the purpose of the unit test above is to ensure all dependencies of a specific service have been injected. So GetService<T>
is the preferred way to do the testing.
Upvotes: 5
Views: 3120
Reputation: 63367
Once the service is added in the ServiceCollection
, you should be able to get back the ServiceDescriptor
to verify the service scope. Note that ServiceCollection
is an IEnumerable<ServiceDescriptor>
. So you can check it like this:
// Assert
Assert.AreEqual(services.FirstOrDefault(e => e.ServiceType == typeof(IServiceA))?.Lifetime, ServiceLifetime.Scoped);
You don't need to build the service provider from the service collection.
Note that the code above would fail as well if the IServiceA
is not registered. That depends on your requirement, you can modify the code as you want. I've just shown the main idea.
Upvotes: 10