如何对基于清洁架构和CQRS构建的控制器进行单元测试?

How to do Unit Testing for a controller structured upon Clean Architecture and CQRS?

提问人:Aboliii 提问时间:11/15/2023 最后编辑:Mark SeemannAboliii 更新时间:11/15/2023 访问量:36

问:

我有一个产品 API,我的意思是通过 xUnit.net 和最小起订量进行单元测试。顺便说一句,我是单元测试的新手。我看过几个关于通过存储库模式对控制器进行单元测试的视频,但这个视频是 CQRS。下面是表示层 (API)。我从应用程序层调用命令或查询。

[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> GetAllProducts()
{
    var products = await _mediator.Send(new GetAllProductsQuery());
    return Ok(products);
}

我想测试控制器,所以我在 xUnit 项目上添加了对 API 的引用。我试图根据存储库模式从组中构建应用程序层中的命令和查询,但它失败了!

C# 单元测试 最小起订量 xUnit CQRS

评论


答:

4赞 Mark Seemann 11/15/2023 #1

假设(为了简单起见)这是此接口的实例,通过控制器的构造函数注入:_mediatorIMediator

public interface IMediator
{
    Task<IReadOnlyCollection<Product>> Send(GetAllProductsQuery getAllProductsQuery);
}

您可以编写控制器操作的单元测试,如下所示:

[Fact]
public async Task GetAllProductsReturnsOk()
{
    var td = new Mock<IMediator>();
    var expected = new[] { new Product() };
    td.Setup(m => m.Send(It.IsAny<GetAllProductsQuery>())).ReturnsAsync(expected);
    var sut = new ProductsController(td.Object);

    var result = await sut.GetAllProducts();

    var ok = Assert.IsAssignableFrom<OkObjectResult>(result);
    Assert.Equal(expected, ok.Value);
}

此测试使用我的标准测试角色名称AAA 布局启发式。

评论

0赞 Aboliii 11/15/2023
谢谢马克。自从我加入 Stack 以来,您一直给了我很大的帮助!我尝试了几乎相同的代码。控制器中已经定义了构造函数,但是我在定义 sut 变量时出错。所以我向控制器添加了另一个构造函数,这次我在调试时遇到了 System.NullReferenceException 错误!
0赞 Aboliii 11/15/2023
我的错误!我应该只为 IMediator 定义一个单独的构造函数。谢谢
0赞 Sergey K 11/15/2023
单元测试:它测试了多个东西,但不是测试名称中的内容。