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

已配置Mock,为何GetUserByUsernameAndPassword()仍返回null?

已配置Moq Mock但GetUserByUsernameAndPassword仍返回null的原因及解决办法

1. 核心问题:误用未配置的Mock实例

你在测试代码里犯了关键错误:配置好Mock对象后,实例化UserService时用了全新的未配置Mock。

看测试里的这段代码:

// 这里创建并配置了一个Mock<IUserRepository>
var userRepository = new Mock<IUserRepository>()
    .Setup(_ => _.GetUserByUsernameAndPassword(It.IsAny<string>(), It.IsAny<string>()))
    .Returns(new User
    {
        Password = "b",
        EmailAddress = "asdadsa!yaho",
        Name = "asa"
    });

// 但这里却新建了一个空的Mock实例传给UserService,之前配置的完全没用到!
var userService = new UserService(new Mock<IUserRepository>().Object);

正确做法是把已经配置好的Mock实例传给UserService,也就是用userRepository.Object代替新创建的Mock。

2. 额外注意:密码参数的匹配问题

业务方法中调用GetUserByUsernameAndPassword时,第二个参数是userCredential.Password.DoHash(),而你测试里传入的密码是"b",Mock中设置的返回用户密码是"b"。如果DoHash()会改变密码值,那么即使Mock配置正确,参数也可能不匹配导致返回null。

修正后的完整测试代码

[Fact]
public async Task RegisterUser_MustReturnPhoneNumberError2()
{
    // 配置Mock并保存实例
    var userRepositoryMock = new Mock<IUserRepository>();
    userRepositoryMock.Setup(_ => _.GetUserByUsernameAndPassword(
            It.IsAny<string>(), 
            // 如果知道DoHash()的结果,可以写具体值,比如假设DoHash("b")返回"hashed_b"
            // It.Is<string>(p => p == "hashed_b")
            It.IsAny<string>()
        ))
        .Returns(new User
        {
            Password = "b", // 或者这里改成哈希后的值,和业务逻辑一致
            EmailAddress = "asdadsa!yaho",
            Name = "asa"
        });

    // 使用配置好的Mock实例
    var userService = new UserService(userRepositoryMock.Object);

    var expectation = new UserResponseDto
    {
        Status = new StatusMaker().ErrorStatus("TEXT")
    };

    var a = new UserCredentialRequestDto
    {
        EmailAddress = "a",
        Password = "b",
        PhoneNumber = "c"
    };

    var res = await userService.LoginUser(a);

    Assert.Equal(expectation.Status.Message, res.Status.Message);
}

补充说明

  • 如果你想让Mock更严谨,可以把It.IsAny<string>替换为实际调用时的参数值,比如电话号码"c"和密码哈希后的结果。
  • 业务方法中的LoginUser标记为async,但内部调用的是同步的GetUserByUsernameAndPassword,如果实际仓储方法是异步的(比如返回Task<User>),还需要调整Mock的ReturnsAsync而不是Returns。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:40:22