确认是否在使用中间件。

8

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

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,但是关于单元测试 .Net Core 中间件的存在性的相关材料非常少。

非常感谢您的帮助!

3个回答

9

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

你唯一能做的事情就是检查底层的ApplicationBuilder.Use方法是否被调用,并传入了某些请求委托。

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

因此,这将非常复杂。我建议你编写一个集成测试,以检查对于一个请求,你的中间件是否被正确调用,并且能够完成其应有的功能。


我很担心这一点,但似乎我必须这样做来测试它。遗憾的是,没有一个IApplicationBuilderIServiceProvider方法可以提供给你管道或确认特定类(甚至接口)是否在管道中。 - Phillip Copley
2
好的,正如我所说,你可以轻松地测试 IApplicationBuilder.Use 是否被调用了,但由于 UseMiddleware 的工作方式,你将无法确定它是否是你类型的中间件。至少在实际调用请求委托之前是这样的。 - poke

1
除了 @poke 的回答,您可能还想查看 ASP.NET Core 诊断堆栈的一部分 中间件分析。还有一个示例应用程序可用。

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


0
这是我完成它的方式:

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

这仅在中间件列表中只有一个中间件时有效。

你使用哪个版本的 .Net Core 进行测试?我使用 .Net Core 3.1 无法运行。 - user2966445
它是 .NET Core 3.1。 - delepster
假设列表中只有一个中间件,您无法创建集成测试。 - Wilko van der Veen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接