我更喜欢让我的处理程序免于很难测试的ASP.NET基础结构(是的,甚至在ASP.NET Core中)。但有时它会发生,你有一个依赖,比如UserManager(我想知道有一天为什么它不是一个接口),HttpContext等等。单元测试变成了一个嘲弄地狱。
我尝试使用集成测试来处理它,方法是创建一个TestServer并为每个api调用初始化所有ASP.NET基础结构。它工作得很好,但如果我想测试我的处理程序的简单逻辑,有时看起来有点矫枉过正。虽然它解决了模拟ASP.NET基础结构的技术问题,但它仍然存在将ASP.NET基础结构放入处理程序的架构问题(如果您考虑的话)。
我想知道处理它的推荐方法是什么?
答案 0 :(得分:5)
我感觉到你的痛苦。我偶然发现了吉米·博加德(Jimmy Bogard)的一个奇妙的blob post,它使用了马丁福勒所称的Subcutaneous Tests来处理这个问题。我将向那些专家留下深刻的解释,但简而言之,皮下测试只是避免了UI的所有难以测试的方面。
无耻插件:我目前正在编写一个wiki,在github上的示例端到端项目中演示这些模式。这并不难理解,但可能有太多的代码要发布SO答案。
总结:
要解决:
基本上就是这样。每次针对其中一个处理程序运行集成测试时:
我会在答案中添加更多代码示例,但在博文和我提供的wiki之间,可以更容易地遵循那里的代码示例。
答案 1 :(得分:1)
我会说这取决于你最终想要获得的信心程度。如果你想确保整个系统按预期工作,那么使用TestServer
进行集成测试可能就好了。
然而,MediatR的一个优点是,它允许您将业务逻辑与使用它的应用程序分离,这就是为什么在最高级别,让我们说在控制器中,没有逻辑,只是委托给调解员。
话虽这么说,你是对的,有时你的逻辑需要来自托管应用程序的信息。一个例子是发出请求的用户,可以在HTTP上下文中访问。
在这种情况下,如果您想避免设置测试HTTP服务器来测试逻辑工作,您可以在抽象中表示该信息,然后您的处理程序将依赖于该抽象。然后,您的测试可以模拟该依赖关系,同时将真实系统用于其他所有事情。
这有意义吗?
答案 2 :(得分:1)
Mediatr或者不,你应该总是尝试只在控制器中的逻辑上进行非常基本的传递,并从那里调用注入的业务逻辑类来完成实际的工作。当您向它们注入与此业务逻辑的接口时,您的控制器就会出现这种情况。在单元测试中很容易模拟依赖关系,如果他们正确地实现了这些接口并且只做路由输入/输出的基本工作,那么测试可以集中精力。您的实际业务逻辑可以更轻松地进行测试。
对于那些静态的类,例如读取web.config设置,我喜欢的一个策略是围绕它们创建一个接口包装类。虽然ConfigurationManager是静态的,但我仍然可以编写一个带有接口的常规类,我将方法或属性设置为从Configuration Manager读取特定设置(最好是语义命名)。现在,我可以通过模拟界面和设置不同的返回值,轻松地在我的测试中模拟任何已配置的设置(或缺少它)。