首页 > 解决方案 > 使用 xunit 和 moq 的 net core api 控制器单元测试

问题描述

我有一些 api 控制器方法,我想添加一些单元测试。我正在使用 xunit 和 moq 并使用 asp net core 在 c# 中编写。

一种方法的示例是:

public async Task<ActionResult<List<StatusDTO>>> Get()
{
    return await _statusservice.GetStatusesAsync();
}

此时,我的控制器方法只是返回服务层方法返回的 dto。将来它可能会更改为返回特定的视图模型。

我已阅读https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/testing?view=aspnetcore-2.2以获取有关测试控制器的一些指导。

我的问题是:例如上面的单元测试是否只包括 - 检查返回类型是否ActionResult<StatusDTO>和/或(使用最小起订量)验证服务方法已被调用。

我是否应该设置我的服务方法来返回一个模拟StatusDTO并针对它做一些断言。在这种情况下,我看不到这样做的好处,因为那将是测试服务方法而不是它,我会在服务方法测试中涵盖它。

对不起,如果这看起来很基本 - 我在编写单元测试方面的知识和经验非常有限。谢谢你的帮助。

标签: unit-testingasp.net-corexunit

解决方案


一般来说,您不应该成为单元测试控制器。有警告,但因此是“一般”。例如,如果您有一些辅助方法,则对控制器的特定方法进行单元测试可能是合适的,但是操作通常太复杂而无法进行可靠的单元测试。

有一个HttpContext、一个ActionContextSessionUser等 - 所有可能以各种方式潜在利用的依赖项,所有这些依赖项都需要通过模拟来满足。当然,您可以模拟所有依赖项,但是当您这样做时,您的测试代码比实际应用程序代码长 100 倍,最终您的测试是通过还是失败开始与是否您已经正确地模拟了所有内容,而不是您的实际应用程序代码是否正确。

然后,特别是在这种情况下,您的操作只做一件事:调用服务类的方法。服务类是应该进行单元测试的,假设它是联合测试的,那么为此操作添加单元测试不会增加任何内容。

总而言之,动作更适合集成测试。您应该将尽可能多的操作逻辑分解到可以单独进行单元测试的方法或类中(您已经完成了),然后您只需测试集成,即特定请求会导致特定响应。

有关 ASP.NET Core 中的集成测试的更多信息,请参阅相关文档。它更适合 Razor 页面,但无论您是在集成测试 Razor 页面、MVC 操作还是 API 操作,方法都是相同的。这只是一个导致响应的请求。


推荐阅读