确认中间件正在使用中

Confirm that middleware is in use

我正在尝试通过单元测试确认中间件确实已添加到管道中。我有以下添加中间件的静态方法。这是我正在测试的。

public static class HandleDbUpdateExceptionExtensions
{
    public static IApplicationBuilder UseDbUpdateExceptionHandler(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<DbUpdateExceptionHandler>();
    }
}

我知道它确实有效,因为中间件在我的网站上运行。但是,我想编写一个单元测试以确保它始终包含在未来的构建中。但是,我的单元测试失败了:

[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 为空,因此测试当前失败。我认为它失败了,因为我只是在嘲笑 IApplicationBuilder,但是关于单元测试 existance of .Net Core 中间件的在线相关 material 很少。

非常感谢任何帮助!

UseMiddleware 实际上是一种扩展方法,它将创建一个在内部使用您的中间件的 RequestDelegate。该委托做了很多事情,因此您很难测试它是否会正确注册您的实际中间件类型。

你唯一真正能做的就是检查底层 ApplicationBuilder.Use method 是否被 some 请求委托调用。

或者,您也可以通过构建应用程序管道并执行它来实际调用中间件。但这需要您正确设置依赖注入(因为 UseMiddleware() 的委托将使用它)并且所有中间件的依赖项都正确设置。

所以这会非常复杂。我建议你写一个 integration test 而不是检查请求,你的中间件将被正确调用并且可以做它应该做的事情。

除了@poke 的回答之外,您可能还想查看 middleware analysis which is part of the ASP.NET Core Diagnostics stack. There is also a sample application 是否可用。

它基本上做的是用 AnalysisMiddleware 包围每个中间件,后者将信息写入诊断源。您可以在测试中创建一个诊断源侦听器并验证是否调用了每个中间件。但是,这需要您执行中间件管道,这实际上意味着您要创建一个 integration 测试。

这是我完成的方法:

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>();

当列表中只有一个中间件时,此方法有效。