【问题标题】:MediatR and CQRS testing. How to verify that handler is called?MediatR 和 CQRS 测试。如何验证调用了该处理程序?
【发布时间】:2022-01-08 19:21:14
【问题描述】:

我目前正在尝试在我的项目中实施MediatR,并进行测试。我想介绍一下在发送请求时是否调用了处理程序的Handle

我有这个问题

public class GetUnitsQuery : IRequest<List<UnitResponse>>
{
}

处理程序:

public class GetUnitsHandler : IRequestHandler<GetUnitsQuery, List<UnitResponse>>
{
    readonly IUnitRepository UnitRepository;
    readonly IMapper Mapper;

    public GetUnitsHandler(IUnitRepository unitRepository, IMapper mapper)
    {
        this.UnitRepository = unitRepository;
        Mapper = mapper;
    }

    public async Task<List<UnitResponse>> Handle(GetUnitsQuery request, CancellationToken cancellationToken)
    {
        return Mapper.Map<List<UnitResponse>>(UnitRepository.GetUnits());
    }
}

从控制器发送请求:

var result = await Mediator.Send(query);

任何想法如何测试Handler 在使用MoQ 指定特定Query 时是否被调用?

【问题讨论】:

  • 这样做有什么意义?这是 MediatR 的责任,不是你的。
  • 我完全同意@Orhun,如果您使用的是 MediatR(产品),则不应对其进行测试...如果您正在实施自己的调解器,则应对其进行测试,但我对此表示怀疑从上下文来看是这样的......无论如何,我认为该产品带有一种机制,可以防止在没有处理程序的情况下注册查询......所以......为什么要担心?

标签: c# .net moq cqrs mediatr


【解决方案1】:

我没有使用 MoQ 来检查接收到的对特定处理程序的调用。但是,如果我使用 Nsubsitute 和 SpecFlow,我会在测试中执行类似的操作。

        var handler = ServiceLocator.Current.GetInstance<IRequestHandler<GetUnitsQuery, List<UnitResponse>>>();
        handler.Received().Handle(Arg.Any<GetUnitsQuery>(), Arg.Any<CancellationToken>());

【讨论】:

    【解决方案2】:

    就像其他人在 cmets 中所说的那样,您不需要测试 Mediator 的内部。

    你的测试边界就是你的应用程序,所以假设一个控制器是这样的:

    public class MyController : Controller 
    {
        private readonly IMediator _mediator;
    
        public MyController(IMediator mediator)
        {
            _mediator = mediator;
        }
    
        public async IActionResult Index()
        {
            var query = new GetUnitsQuery();
    
            var result = await Mediator.Send(query);
    
            return Ok(result);
        }
    }
    

    我会验证 Mediator 是这样调用的:

    public class MyControllerTests 
    {
        [SetUp]
        public void SetUp()
        {
            _mockMediator = new Mock<IMediator>();
            _myController = new MyController(_mockMediator.Object)
        }
    
        [Test]
        public async void CallsMediator()
        {
            // Arranged
            _mockMediator.SetUp(x=> x.Send(It.IsAny<GetUnitsQuery>()))
                .Returns (new List<UnitResponse>());
    
            // Act
            await _myController.Index();
    
            // Assert
            _mockMediator.Verify(x=> x.Send(It.IsAny<GetUnitsQuery>()), Times.Once);
        }
    }
    

    【讨论】:

    • 感谢您的回答,但我自己了解的就这么多了。我是否必须对其进行测试并不重要,我只是想就我所问的问题提供帮助:)
    • 抱歉,您缺少单元测试的基础知识,只测试您的代码。
    猜你喜欢
    • 2021-06-22
    • 2019-08-25
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多