MediatR 和 CQRS 测试。如何验证调用了该处理程序?
Posted
技术标签:
【中文标题】MediatR 和 CQRS 测试。如何验证调用了该处理程序?【英文标题】:MediatR and CQRS testing. How to verify that handler is called? 【发布时间】: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(产品),则不应对其进行测试...如果您正在实施自己的调解器,则应对其进行测试,但我对此表示怀疑从上下文来看是这样的......无论如何,我认为该产品带有一种机制,可以防止在没有处理程序的情况下注册查询......所以......为什么要担心? 【参考方案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);
【讨论】:
感谢您的回答,但我自己了解的就这么多了。我是否必须对其进行测试并不重要,我只是想就我所问的问题提供帮助:) 抱歉,您缺少单元测试的基础知识,只测试您的代码。以上是关于MediatR 和 CQRS 测试。如何验证调用了该处理程序?的主要内容,如果未能解决你的问题,请参考以下文章
MediatR CQRS模式解决将消息发送与消息处理进行了解耦,他同时支持异步和同步来发送和监听消息.