如何在另一个Handler中Mock Mediator Get Query?返回Null问题排查
问题原因及解决办法
你的单元测试里result返回null,是因为Moq的匹配规则没生效,核心有两个问题:
1. 参数匹配错误,Mock未触发
你在Setup里写的:
x.Send(new GetSomethingQuery(It.IsAny<string>()), CancellationToken.None)
- 第一个参数:
new GetSomethingQuery(...)是新创建的实例,Moq默认按对象引用匹配,和Handler里new GetSomethingQuery(request.Value)的实例不是同一个,匹配失败。 - 第二个参数:硬写
CancellationToken.None,但Handler里传的是方法参数cancellationToken,如果测试中这个token不是None,同样会匹配失败。
修正方式:用类型匹配替代实例/固定值匹配:
x.Send(It.IsAny<GetSomethingQuery>(), It.IsAny<CancellationToken>())
如果要匹配特定的Value,可以更精准:
x.Send(It.Is<GetSomethingQuery>(q => q.Value == "目标值"), It.IsAny<CancellationToken>())
2. 返回值错误使用It.IsAny
It.IsAny<T>()是Moq用来匹配参数的语法,不能用在返回值里。你写的:
ReturnsAsync(Result.Fail(new NotFoundError(It.IsAny<string>())))
这会生成一个错误信息为占位符的无效实例,正确做法是传入具体错误内容:
ReturnsAsync(Result.Fail(new NotFoundError("资源未找到")))
修改后的完整测试代码
[Fact] public async Task MyTest() // 注意:异步测试要用async Task,不要用async void { // 配置Mock _mediatorStub .Setup(x => x.Send(It.IsAny<GetSomethingQuery>(), It.IsAny<CancellationToken>())) .ReturnsAsync(Result.Fail(new NotFoundError("测试错误信息"))); // 执行测试 var testResult = await Sut.Handle(new MyCommand()); // 可选:添加断言验证结果符合预期 Assert.True(testResult.IsFailed); Assert.IsType<NotFoundError>(testResult.Errors.FirstOrDefault()); }
补充:异步单元测试尽量用async Task代替async void,后者在测试框架中无法正确捕获异常。
内容的提问来源于stack exchange,提问作者user7849697
相关产品推荐
相关产品推荐

