You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中使用Moq模拟MediatR进行集成测试返回null问题排查

问题排查与修复

你的测试返回null且不符合预期的核心原因有两个:

1. Moq未正确匹配MediatR的泛型Send方法

MediatR的IMediator.Send是泛型方法,定义为:

Task<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default);

你当前的Setup未指定泛型参数,Moq无法识别你要模拟的是返回Result<Unit>的Send调用,实际调用时未触发模拟逻辑,因此返回null。

2. 测试预期对象未正确初始化

你用new Result<Unit>()创建的预期对象未设置Error属性值,即便模拟成功,断言也会失败。应使用Result<Unit>.Failure()静态方法创建符合预期的失败结果。


修复后的测试代码

[TestFixture]
public class UserControllerTests
{
    private Mock<IMediator> _mockMediator;
    private UserController _userController;

    [SetUp] // 改用SetUp初始化,符合NUnit规范
    public void Setup()
    {
        _mockMediator = new Mock<IMediator>();
        _userController = new UserController(_mockMediator.Object);
    }

    [Test]
    public async Task DeleteUser_NotSuccessful_NoIdDeleted()
    {
        // 用Failure方法创建预期的失败结果
        var expected = Result<Unit>.Failure("User Id doesn't exsist");
        
        // 指定泛型参数,精准匹配目标Send调用
        _mockMediator.Setup(x => x.Send<Result<Unit>>(
                It.Is<DeleteUserCommand>(cmd => cmd.UserId == 6),
                It.IsAny<CancellationToken>()))
            .ReturnsAsync(expected); // 替代Task.FromResult,代码更简洁

        var result = await _userController.DeleteUser(6);

        Assert.AreEqual("User Id doesn't exsist", result.Value.Error);
        Assert.IsFalse(result.Value.IsSuccess);
    }

    [Test]
    public async Task DeleteUser_Successful_UserIdDeleted()
    {
        var expected = Result<Unit>.Success(Unit.Value);
        
        _mockMediator.Setup(x => x.Send<Result<Unit>>(
                It.Is<DeleteUserCommand>(cmd => cmd.UserId == 7),
                It.IsAny<CancellationToken>()))
            .ReturnsAsync(expected);

        var result = await _userController.DeleteUser(7);

        Assert.IsTrue(result.Value.IsSuccess);
        Assert.AreEqual(Unit.Value, result.Value.Value);
    }
}

额外优化建议

  • 用[SetUp]替代构造函数初始化测试依赖,更符合测试框架规范且灵活
  • 对DeleteUserCommand的UserId做精准匹配,避免测试逻辑被其他ID的调用干扰
  • 使用ReturnsAsync简化异步返回值的模拟

内容的提问来源于stack exchange,提问作者Sean Elias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:10:55