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

Moq传入不同值给Returns却返回相同结果的问题排查

问题排查与解决

嘿,我仔细梳理了你的测试代码和相关实现,找到问题的核心原因了!

核心问题:Moq参数匹配与实际调用不匹配

你在Mock IDbConnectionExtensionsWrapper.Get方法时,Setup的参数匹配逻辑写错了:

// 你原来的写法
extensionWrapper
    .Setup(ex => ex.Get<User>(It.IsAny<IDbConnection>(), It.IsAny<IDbTransaction>(), It.IsAny<int>()))
    .Returns(Task.FromResult(users));

但看你的仓储代码,调用Get时只传了第一个参数,后两个参数用的是默认值null:

var users = await this.ConnectionWrapper
    .Get<User>(this.Connection);

再对照IDbConnectionExtensionsWrapper.Get的定义,后两个参数是可空类型:

public async Task<IEnumerable<T>> Get<T>(
    IDbConnection connection,
    IDbTransaction? transaction = null,
    int? timeout = null)

你用It.IsAny<int>()匹配的是非空int值,但实际传递的是int?类型的null,两者完全不匹配!第一个测试用例成功可能是偶然情况,后续测试因为参数不匹配,Moq返回了默认值(空枚举)。

修复方案

把Setup里的参数匹配改成对应可空类型的匹配即可,两种方式任选:

方式1:匹配任意可空值(更灵活)

extensionWrapper
    .Setup(ex => ex.Get<User>(
        It.IsAny<IDbConnection>(),
        It.IsAny<IDbTransaction?>(), // 匹配可空的事务参数
        It.IsAny<int?>())) // 匹配可空的超时参数
    .Returns(Task.FromResult(users));

方式2:精准匹配null(更贴合你的仓储调用逻辑)

extensionWrapper
    .Setup(ex => ex.Get<User>(
        It.IsAny<IDbConnection>(),
        null,
        null))
    .Returns(Task.FromResult(users));

额外验证小技巧

可以在每个测试用例末尾添加Verify断言,确认Mock的方法确实被调用了,方便快速排查参数匹配问题:

extensionWrapper.Verify(
    ex => ex.Get<User>(It.IsAny<IDbConnection>(), null, null), 
    Times.Once, 
    "Get方法应该被调用一次");

小优化建议

  1. 你的GenerateUsers方法里,所有用户的Salt和Hash都是同一个值,把salt的生成逻辑放到循环内部,让每个用户拥有独立的salt会更合理:
private static IEnumerable<User> GenerateUsers(int count)
{
    var random = new Random();
    var users = new List<User>();
    for (var i = 0; i < count; i++)
    {
        using var crypto = new RNGCryptoServiceProvider();
        var salt = new byte[16];
        crypto.GetBytes(salt);
        users.Add(new User
        {
            Id = i,
            Username = Convert.ToString(i),
            Salt = salt,
            Hash = salt,
        });
    }
    return users;
}
  1. xUnit中Assert.AreEqual可以换成更简洁的Assert.Equal,功能完全一致:
Assert.Equal(userCount, usersFromRepository.Count());

内容的提问来源于stack exchange,提问作者Liam Mueller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 15:52:47