I am trying to confirm via a unit test that middleware is actually being added to the pipeline. I have the following static method that adds the middleware. This is what I am testing.
public static class HandleDbUpdateExceptionExtensions
{
public static IApplicationBuilder UseDbUpdateExceptionHandler(this IApplicationBuilder builder)
{
return builder.UseMiddleware<DbUpdateExceptionHandler>();
}
}
I know it's actually working because the middleware runs on my site. However, I'd like to write a unit test to ensure it's always included in future builds. My unit test, however, fails:
[Fact(DisplayName = "Exception handler is added to IApplicationBuilder")]
public void DbUpdateExceptionHandler_Added_To_IApplicationBuilder()
{
var builder = new Mock<IApplicationBuilder>().Object;
builder.UseDbUpdateExceptionHandler();
Assert.NotNull(builder.ApplicationServices);
//var test = builder.ApplicationServices.GetService(typeof(DbUpdateExceptionHandler));
}
builder.ApplicationServices
is null so the test currently fails. I assume that it is failing because I am just mocking IApplicationBuilder
but there is very little relevant material online about unit testing the existance of .Net Core middleware.
Any help is greatly appreciated!
UseMiddleware
is actually an extension method that will create a RequestDelegate that uses your middleware internally. That delegate does quite a lot of things, so it would be very difficult for you to test that it will properly register your actual middleware type.
The only thing you can really do is to check that the underlying ApplicationBuilder.Use
method was called with some request delegate.
Alternatively, you could also actually invoke the middleware, by building the application pipeline and executing it. But that will require that you set up dependency injection properly (since the delegate from UseMiddleware()
will use that) and that all your middleware’s dependencies are set up properly.
So this is going to be very complicated. I would suggest you to write an integration test instead that checks that for a request, your middleware will be invoked properly and can do what it should do.
In addition to @poke's answer you might want to look into middleware analysis which is part of the ASP.NET Core Diagnostics stack. There is also a sample application available.
What it basically does is surrounding each middleware with the AnalysisMiddleware
which writes information to a diagnostics source. You could create a diagnostics source listener in your tests and validate that each middleware is invoked. However, this requires you to execute the middleware pipeline which effectively means your creating an integration test.
Here is the way I've done it:
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton(Mock.Of<ILogger<ExceptionHandlingMiddleware>>());
var applicationBuilder = new ApplicationBuilder(serviceCollection.BuildServiceProvider());
applicationBuilder.UseExceptionHandlingMiddleware();
var app = applicationBuilder.Build();
app.Target.Should().BeOfType<ExceptionHandlingMiddleware>();
This works when there is only one middleware in the list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With