J'ai un projet .NET Core 2.0 qui contient un modèle de référentiel et des tests xUnit.
Maintenant, voici une partie de son code.
Contrôleur:
public class SchedulesController : Controller
{
private readonly IScheduleRepository repository;
private readonly IMapper mapper;
public SchedulesController(IScheduleRepository repository, IMapper mapper)
{
this.repository = repository;
this.mapper = mapper;
}
[HttpGet]
public IActionResult Get()
{
var result = mapper.Map<IEnumerable<Schedule>, IEnumerable<ScheduleDto>>(source: repository.items);
return new OkObjectResult(result);
}
}
Ma classe de test:
public class SchedulesControllerTests
{
[Fact]
public void CanGet()
{
try
{
//Arrange
Mock<IScheduleRepository> mockRepo = new Mock<IScheduleRepository>();
mockRepo.Setup(m => m.items).Returns(new Schedule[]
{
new Schedule() { Id=1, Title = "Schedule1" },
new Schedule() { Id=2, Title = "Schedule2" },
new Schedule() { Id=3, Title = "Schedule3" }
});
var mockMapper = new Mock<IMapper>();
mockMapper.Setup(x => x.Map<Schedule>(It.IsAny<ScheduleDto>()))
.Returns((ScheduleDto source) => new Schedule() { Title = source.Title });
SchedulesController controller = new SchedulesController(repository: mockRepo.Object, mapper: mockMapper.Object);
//Act
var result = controller.Get();
//Assert
var okResult = result as OkObjectResult;
Assert.NotNull(okResult);
var model = okResult.Value as IEnumerable<ScheduleDto>;
Assert.NotNull(model);
}
catch (Exception ex)
{
//Assert
Assert.False(false, ex.Message);
}
}
}
Problème auquel je suis confronté.
Mon problème est que lorsque j'exécute ce code avec un contexte de base de données et que j'exécute la méthode Get()
, cela fonctionne bien, cela me donne tous les résultats.
Mais lorsque j'essaie d'exécuter le scénario de test, il ne renvoie aucune donnée de l'objet Dto. Quand j'ai débogué, j'ai trouvé que
J'obtiens mon objet de test dans le contrôleur en utilisant mockRepo
.
Mais il semble que le mappeur automatique ne soit pas initialisé correctement, car lors du mappage, il ne renvoie rien dans
var result = mapper.Map<IEnumerable<Schedule>, IEnumerable<ScheduleDto>>(source: repository.items);
Ce que j'ai essayé jusqu'à présent?
J'ai suivi toutes ces réponses mais ça ne marche toujours pas.
Mocking Mapper.Map () dans les tests unitaires
Comment simuler une transformation de liste à l'aide d'AutoMapper
Donc, j'ai besoin de l'aide de quelqu'un qui est bon dans xUnit et automapper, et j'ai besoin de conseils sur la façon d'initialiser correctement le mappeur simulé.
Enfin, cela a fonctionné pour moi, j'ai suivi cette voie Comment écrire un test xUnit pour le service .net core 2.0 qui utilise AutoMapper et l'injection de dépendance?
Ici, je poste ma réponse et ma classe de test, si nécessaire, d'autres SO peuvent utiliser.
public class SchedulesControllerTests
{
[Fact]
public void CanGet()
{
try
{
//Arrange
//Repository
Mock<IScheduleRepository> mockRepo = new Mock<IScheduleRepository>();
var schedules = new List<Schedule>(){
new Schedule() { Id=1, Title = "Schedule1" },
new Schedule() { Id=2, Title = "Schedule2" },
new Schedule() { Id=3, Title = "Schedule3" }
};
mockRepo.Setup(m => m.items).Returns(value: schedules);
//auto mapper configuration
var mockMapper = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new AutoMapperProfile());
});
var mapper = mockMapper.CreateMapper();
SchedulesController controller = new SchedulesController(repository: mockRepo.Object, mapper: mapper);
//Act
var result = controller.Get();
//Assert
var okResult = result as OkObjectResult;
if (okResult != null)
Assert.NotNull(okResult);
var model = okResult.Value as IEnumerable<ScheduleDto>;
if (model.Count() > 0)
{
Assert.NotNull(model);
var expected = model?.FirstOrDefault().Title;
var actual = schedules?.FirstOrDefault().Title;
Assert.Equal(expected: expected, actual: actual);
}
}
catch (Exception ex)
{
//Assert
Assert.False(false, ex.Message);
}
}
}
J'avais besoin d'injecter IMapper
, d'utiliser ProjectTo
pour obtenir un IQueryable
mappé, puis d'implémenter un peu plus de logique sur la requête après la carte. Voici donc ce que j'ai fait pour me moquer:
var models = new object[]
{
⋮
}.AsQueryable();
var mapper = new Mock<IMapper>();
mapper.Setup(x => x.ProjectTo(
It.IsAny<IQueryable>(),
It.IsAny<object>(),
It.IsAny<Expression<Func<object, object>>[]>()))
.Returns(models);