【问题标题】:Mock repository is returning null模拟存储库返回 null
【发布时间】:2021-12-08 06:58:38
【问题描述】:

我正在为服务类编写一个简单的 xunit 测试用例。 我嘲笑了_userAPIRepository,但它返回 null 值。它应该返回teacherDetails

下面是服务类方法和xunit测试用例方法。

服务方式

public async Task<List<TeacherDto>> GetTeacherDetails(Teacher teacher)
{
    List<TeacherDto> teacherDetails = new List<TeacherDto>();
    UserByUsername userByUsername = new UserByUsername
    {
        Username = teacher.Name,
        Id       = teacher.Id
    };

    teacherDetails = await _userServiceAPI.GetUserIdsByName(userByUsername);
         
    return teacherDetails;
         
}

xunit 测试用例

[Fact()]
public async Task GetUserDetails()
{
    //Arrange
    List<TeacherDto> teacherDetails = ServiceDataSource.teacherDetails();
    Teacher teacher =  ServiceDataSource.teacher();
     
    UserByUsername userByUsername = new UserByUsername
    {
        Username = teacher.Name,
        Id       = teacher.Id
    };
     
    _userAPIRepository.Setup(x => x.GetUserIdsByName(userByUsername)).Returns(Task.FromResult(teacherDetails);
            
     
    var result = await _userServiceAPI.GetTeacherDetails(teacher);
     
    //Assert
    Assert.True(result.Count > 0);
}

【问题讨论】:

  • 使用参数匹配器从模拟中获取所需的行为。当参数设置与执行测试时传入的参数不匹配时,模拟默认返回 null

标签: c# unit-testing asp.net-core asp.net-core-webapi moq


【解决方案1】:

当参数设置与执行测试时传入的参数不匹配时,mock 默认返回 null。在本例中,使用了与在测试对象中创建的实例不匹配的实际实例/引用。

使用参数匹配器从模拟中获取所需的行为,因为参数是在被测对象中初始化的。

[Fact()]
public async Task GetUserDetails() {
    //Arrange
    List<TeacherDto> teacherDetails = ServiceDataSource.teacherDetails();
    Teacher teacher =  ServiceDataSource.teacher();
     
    _userAPIRepository
        .Setup(x => x.GetUserIdsByName(It.Is<UserByUsername>(u => 
            u.Username == teacher.Name && u.Id == teacher.Id)))
        .ReturnsAsync(teacherDetails);
            
    //Act         
    var result = await _userServiceAPI.GetTeacherDetails(teacher);
     
    //Assert
    Assert.True(result.Count > 0);
}

注意使用It.Is&lt;&gt; 添加带有特定过滤器/谓词的参数匹配器。

如果不需要实际匹配成员并且只接受任何UserByUsername,则可以使用It.IsAny&lt;&gt; 代替

例如

[Fact()]
public async Task GetUserDetails() {
    //Arrange
    List<TeacherDto> teacherDetails = ServiceDataSource.teacherDetails();
    Teacher teacher =  ServiceDataSource.teacher();
     
    _userAPIRepository
        .Setup(x => x.GetUserIdsByName(It.IsAny<UserByUsername>()))
        .ReturnsAsync(teacherDetails);
            
    //Act         
    var result = await _userServiceAPI.GetTeacherDetails(teacher);
     
    //Assert
    Assert.True(result.Count > 0);
}

参考Moq Quickstart 以更好地了解如何使用该库

【讨论】:

  • 感谢 Nkosi,只需稍加改动即可解决问题。
猜你喜欢
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多