MediatR处理程序中的ASP.NET基础结构

Sib*_*Guy 10 asp.net asp.net-web-api mediatr asp.net-core

我更喜欢让我的处理程序免于很难测试的ASP.NET基础结构(是的,甚至在ASP.NET Core中).但有时它会发生,你有一个依赖,比如UserManager(我想知道有一天为什么它不是一个接口),HttpContext等等,单元测试变成了一个嘲弄地狱.

我尝试使用集成测试来处理它,通过创建一个TestServer并为每个api调用初始化所有ASP.NET基础结构.它工作得很好,但如果我想测试我的处理程序的简单逻辑,有时看起来有点矫枉过正.虽然它解决了模拟ASP.NET基础结构的技术问题,但它仍然存在将ASP.NET基础结构放入处理程序的架构问题(如果您考虑的话).

我想知道处理它的推荐方法是什么?

tre*_*orc 5

我感觉到你的痛苦.我偶然发现了吉米·博加德(Jimmy Bogard)的一篇精彩的blob帖子,该文章通过使用Martin Fowler所谓的皮下测试来解决这个问题.我将向那些专家留下深刻的解释,但简而言之,皮下测试只是避免了UI的所有难以测试的方面.

无耻插件:我目前正在编写一个wiki,在github上的示例端到端项目中演示这些模式.这并不难理解,但可能有太多的代码要发布SO答案.

总结一下:

  • 如果您正确使用MediatR,您的控制器应该非常薄,这使得测试它们毫无意义.
  • 您要测试的是您的处理程序.
  • 但是,您希望将处理程序作为现实世界管道的一部分进行测试.

要解决:

  1. 在事务中包装http请求.
  2. 构建一个模拟应用程序Startup.cs的测试工具
  3. 设置测试数据库服务器以执行查询和命令,但也会在每次测试后重置.

基本上就是这样.每次针对其中一个处理程序运行集成测试时:

  • 托管环境是模拟的,但您的应用程序是在现实世界的测试中启动的.
  • 您的查询或命令包含在模仿DbContext的事务中.
  • 处理程序针对真实数据库执行,然后重置.

我会在我的回答中添加更多代码示例,但在博客文章和我提供的wiki之间,可以更容易地遵循那里的代码示例.


Mic*_*iey 1

我想说这取决于你最终想要获得的信心程度。如果您想确保整个系统按预期工作,那么使用 a 进行集成测试TestServer可能是正确的选择。

不过,MediatR 的一个优点是它允许您将业务逻辑与使用它的应用程序解耦,这就是为什么在最顶层(假设在控制器中)没有逻辑,而只是对中介者的委托。

话虽这么说,您是对的,有时您的逻辑需要来自托管应用程序的信息。一个示例是用户发出请求,该请求可在 HTTP 上下文中访问。

在这种情况下,如果您想避免设置测试 HTTP 服务器来测试您的逻辑工作,您可以在抽象中表示该信息,然后您的处理程序将依赖于该抽象。然后,您的测试可以模拟这种依赖关系,同时使用真实的系统来处理其他事情。

那有意义吗?