【问题标题】:Mocked Interface returning NULL模拟接口返回 NULL
【发布时间】:2021-11-08 10:18:34
【问题描述】:

我读过类似的问题,但无法解决我自己的问题。我正在使用 xUnit,当我的一个方法调用时遇到问题,它返回 null 但实际上我已经模拟了它。

界面

public interface IApplicantService
{
    Task<Applicant> AddAsync(Applicant applicant);
    // other methods
}

测试用例

public class ApplicationControllerTests
{
    private readonly Mock<IApplicantService> _mockApplicantService;
    private readonly ApplicantController _applicantController;
    private readonly IMapper _mockMapper;

    public ApplicationControllerTests()
    {
        _mockApplicantService = new Mock<IApplicantService>();

        var mapperConfig = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile(new ResourceToModelProfile());
            cfg.AddProfile(new ModelToResourceProfile());
        });
        _mockMapper = mapperConfig.CreateMapper();

        _applicantController = new ApplicantController(_mockApplicantService.Object, _mockMapper);
    }

    [Fact]
    public async void CreateAsync_WhenApplicantNotExist_ShouldReturn_CreatedAtActionResult_With_Resource()
    {
        var applicantDto = new ApplicantCreateDto
        {
            PersonId = 1,
            VacancyId = 1
        };

        _mockApplicantService.Setup(e => e.AddAsync(It.IsAny<Applicant>()))
                            .Returns(Task.FromResult(new Applicant { Id = 1, PersonId = 1, VacancyId = 1}));

        var result = await _applicantController.CreateAsync(applicantDto);

        var createdAtActionResult = result as CreatedAtActionResult;

        var model = createdAtActionResult.Value as ApplicantResponseDto;

        var actual = model.PersonId;

        Assert.NotNull(model);            
        Assert.Equal(1, actual);
        Assert.NotNull(createdAtActionResult);
    }
}

控制器

[HttpPost]
[Route("CreateAsync")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> CreateAsync([FromBody] ApplicantCreateDto applicantCreateDto)
{
    try
    {
        var applicant = _mapper.Map<ApplicantCreateDto, Applicant>(applicantCreateDto);

        var result = await _applicantService.AddAsync(applicant);
        // here, result is null, but it was mocked to return an Applicant object

        var resource = _mapper.Map<Applicant, ApplicantResponseDto>(result);

        return CreatedAtAction(nameof(GetAsync), new { id = result.Id }, resource);
    }
    catch (ResourceExistException ex)
    {
        return Conflict(ex.Message);
    }
    catch(Exception ex)
    {   
        // log exception             
        return StatusCode(500);
    }
}

模拟的方法返回 null,我得到 System.NullReferenceException

【问题讨论】:

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


    【解决方案1】:

    这就是您的固定单元测试的样子:

    [Fact]
    public async Task CreateAsync_WhenApplicantNotExist_ShouldReturn_CreatedAtActionResult_With_Resource()
    {
        //Arrange
        var applicantDto = new ApplicantCreateDto { PersonId = 1, VacancyId = 1 };
        var applicant = new Applicant { Id = 1, PersonId = 1, VacancyId = 1 };
    
        _mockApplicantService
            .Setup(svc => svc.AddAsync(It.IsAny<Applicant>()))
            .ReturnsAsync(applicant);
    
        //Act
        var result = await _applicantController.CreateAsync(applicantDto);
    
        //Assert
        var createdAtActionResult = Assert.IsAssignableFrom<CreatedAtActionResult>(result);
        var model = Assert.IsAssignableFrom<ApplicationResponseDto>(createdAtActionResult.Value);
        Assert.Equal(1, model.PersonId);
    }
    
    • 我已将 async void 替换为 async Task,这样您的 await 将被正确评估
    • 我已将Returns(Task.FromResult(...)) 更改为ReturnsAsync(...),因为这是specify return value in case of async methods 的推荐方式
    • 我还添加了一些 cmets 以将单元测试的不同阶段彼此分开 (Arrange-Act-Assert)
    • 我已将您的断言逻辑更改为使用 IsAssingableFrom 来验证类型本身,而不是进行空值检查

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      相关资源
      最近更新 更多