I'm creating a random object that I'm expecting back from the test, and using the ReturnsAsync method when setting up the mock repo. The controller inside the Unit Test is returning null, however.
The main difference between my code and a lot of the others is that I'm using AutoMapper to return the DTO object in my controller as an OK object. I'm not sure if that's causing my issue.
Controller Instantiation
private readonly ISuperHeroRepo _repo;
public IMapper _mapper { get; }
public SuperHeroController(ISuperHeroRepo repo, IMapper mapper)
{
_repo = repo;
_mapper = mapper;
}
Repo Method
public async Task<SuperHero> GetSuperHero(int id)
{
return await _db.SuperHeros.FindAsync(id);
}
Mapper Profile
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>();
}
}
Controller Method
[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));
}
}
Unit Test
// 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);
}
Edited: Added the controller instantiation, and the Mapper Profile. Not sure if it'll add more info.