Home > other >  Mock repository is returning null
Mock repository is returning null

Time:10-22

I am writing a simple xunit test case for a service class. I have mocked _userAPIRepository but it returns null value. It should return teacherDetails.

Below is the service class method and xunit test case method.

Service method

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 test case

[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);
}

CodePudding user response:

The mock returns null by default when the arguments setup do not match what was passed in when exercising the test. In the presented case, an actual instance/reference was used which does not match the instance created within the subject under test.

Use argument matcher to get the desired behavior from mock since the argument is initialized within the subject under test.

[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);
}

Note the use of It.Is<> to add an argument matcher with a specific filter/predicate.

If there is no need to actually match the members and just accept any UserByUsername, then It.IsAny<> could be used instead

For example

[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);
}

Reference Moq Quickstart to get a better understanding of how to use that library

  • Related