Appearance
TIP
There is the new ConfigureTestServices() method in ASP.Net Core 5 that purports to do the same thing, but the Lamar team believes that the mechanism shown here will be more "correct" and also allows you to use Lamar specific features.
A new feature in Lamar v5.1 is a long requested way to reliably override service registrations in .Net Core applications bootstrapped by the generic host builder.
Let's say that in test automation scenarios you'd like to override some of the services in your normal application with testing stubs or to overwrite some kind of configuration. What you need to do is to take the IHostBuilder
or IWebHostBuilder
just as it is built by your application's bootstrapping, but apply service registrations that take precedence in Lamar over other registrations. That's a little trickier than you might think because the HostBuilder
/ WebHostBuilder
applies service registrations in different places during bootstrapping, with registrations from Startup.ConfigureServices()
taking precedence in normal usage.
That's where the new OverrideServices()
extension method comes into play. As an example, let's say that in a test harness we want to just replace the normal ASP.Net Core IServer
service with a fake implementation called FakeServer
. The following is the code to do exactly that:
cs
[Fact]
public void sample_usage_of_overrides()
{
var builder = Program
.CreateHostBuilder(Array.Empty<string>())
// This is our chance to make service overrides
.OverrideServices(s => { s.For<IServer>().Use<FakeServer>(); });
using var host = builder.Build();
host.Services.GetRequiredService<IServer>()
.ShouldBeOfType<FakeServer>();
}
In the code above, the lambda passed into the OverrideServices()
method is executed in the Lamar Container
initialization after all other other explicit registrations and policies have been combined. In effect, this means that any registrations -- or removal of registrations -- in the OverrideServices()
call are guaranteed to be processed last and reliably override any original registrations.
The OverrideServices()
extension is only available for IHostBuilder
.
If you are needing to create a test client or server to run integration tests you will need to use the ConfigWebHost()
method of IHostBuilder
to specifically create a test server, otherwise using host.GetTestServer()
or host.GetTestClient()
will throw a System.InvalidCastException. Additionally you'll want to use StartHost()
rather than Build()
For example:
cs
[Fact]
public async Task sample_of_testing_with_client()
{
// Arrange
var builder = Program.CreateHostBuilder(Array.Empty<string>())
// Make service overrides
.OverrideServices(s => {
s.For<IServer>().Use<FakeServer>();
})
.ConfigureWebHost(webHost =>
{
// Add TestServer
webHost.UseTestServer();
});
// Start the test server
var host = await builder.StartAsync();
// Get a test client and do anything you need here like adding headers
var client = host.GetTestClient();
// Act
var response = await client.GetAsync("api/controller/action");
var content = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(result.StatusCode, StatusCodes.Status200OK);
}