使用ReturnsAsync返回Null来模拟期望对象的存储库



我正在创建一个我期望从测试返回的随机对象,并在设置模拟仓库时使用ReturnsAsync方法。但是,单元测试中的控制器返回null。

我的代码和许多其他代码之间的主要区别是,我使用AutoMapper将控制器中的DTO对象作为OK对象返回。我不确定这是否导致了我的问题。

控制器实例化

private readonly ISuperHeroRepo _repo;
public IMapper _mapper { get; }
public SuperHeroController(ISuperHeroRepo repo, IMapper mapper)
{
_repo = repo;
_mapper = mapper;
}

回购方法

public async Task<SuperHero> GetSuperHero(int id)
{
return await _db.SuperHeros.FindAsync(id);
}

映射配置文件

public class SuperHeroProfiles : Profile
{
public SuperHeroProfiles()
{
//Source -> Target
CreateMap<SuperHero, SuperHeroReadDTO>()
.ForMember(target => target.LegalName, option => option.MapFrom(source => $"{source.LegalFirstName} {source.LegalLastName}"))
.ForMember(target => target.Jurisdiction, option => option.MapFrom(source => $"{source.JurisdictionCity}, {source.JurisdictionState}"));
CreateMap<SuperHero, SuperHeroDTO>();
}
}

控制器方法

[HttpGet("{id}")]
public async Task<ActionResult<SuperHeroReadDTO>> Get(int id)
{
var hero = await _repo.GetSuperHero(id);

if (hero == null)
{
return NotFound("Hero Not Found");
}
else
{
// This is where it might be breaking
return Ok(_mapper.Map<SuperHeroReadDTO>(hero));
}
}

// Instantiated
readonly Mock<ISuperHeroRepo> repoMock = new();
readonly Mock<IMapper> mapperMock = new();
private readonly Random random = new();
........
[Fact]
public async Task Get_WithExistingHero_ReturnsExpectedSuperHero()
{
// Arrange
SuperHero expected = CreateRandomSuperHero();
repoMock.Setup(repo => repo.GetSuperHero(It.IsAny<int>()))
.ReturnsAsync(expected);
var controller = new SuperHeroController(repoMock.Object, mapperMock.Object);
// Act - This returns null. Debugging in the controller, I get the object back from repo
var result = await controller.Get(random.Next());
// Assert
Assert.IsType<SuperHeroReadDTO>(result.Value);
var dto = result.Value;
Assert.Equal(expected.SuperHeroName, dto.SuperHeroName);
Assert.Equal($"{expected.LegalFirstName} {expected.LegalLastName}", dto.LegalName);
Assert.Equal($"{expected.JurisdictionCity}, {expected.JurisdictionState}", dto.Jurisdiction);
}

编辑:添加了控制器实例化和Mapper Profile。不确定是否会添加更多信息。

@shree。Pat18确实是正确的。我最终需要在Unit Test中设置Mapper对象并将其传递回控制器。我将需要重构,但下面是解决它的方法:

[Fact]
public async Task Get_WithExistingHero_ReturnsExpectedSuperHero()
{
// Arrange
SuperHero expected = CreateRandomSuperHero();

repoMock.Setup(repo => repo.GetSuperHero(It.IsAny<int>()))
.ReturnsAsync(expected);
// Setup of the mock Mapper
var mockMapper = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new SuperHeroProfiles());
});
var mapper = mockMapper.CreateMapper();
var controller = new SuperHeroController(repoMock.Object, mapper);
// Act
var result = await controller.Get(random.Next());
// Assert
Assert.IsType<SuperHeroReadDTO>(result.Value);
var dto = result.Value;
Assert.Equal(expected.SuperHeroName, dto.SuperHeroName);
Assert.Equal($"{expected.LegalFirstName} {expected.LegalLastName}", dto.LegalName);
Assert.Equal($"{expected.JurisdictionCity}, {expected.JurisdictionState}", dto.Jurisdiction);
}

最新更新