Problemas na criação de teste de unidade para o ASP .NET MVC
Estou criando alguns testes de unidade para minha classe ASP .NET MVC Controller e me deparei com alguns erros muito estranhos:
Meu código de controlador está abaixo:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(JournalViewModel journal)
{
var selectedJournal = Mapper.Map<JournalViewModel, Journal>(journal);
var opStatus = _journalRepository.DeleteJournal(selectedJournal);
if (!opStatus.Status)
throw new System.Web.Http.HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
return RedirectToAction("Index");
}
Meu código de teste está abaixo:
[TestMethod]
public void Delete_Journal()
{
// Arrange
// Simulate PDF file
HttpPostedFileBase mockFile = Mock.Create<HttpPostedFileBase>();
Mock.Arrange(() => mockFile.FileName).Returns("Test.pdf");
Mock.Arrange(() => mockFile.ContentLength).Returns(255);
// Create view model to send.
JournalViewModel journalViewModel = new JournalViewModel();
journalViewModel.Id = 1;
journalViewModel.Title = "Test";
journalViewModel.Description = "TestDesc";
journalViewModel.FileName = "TestFilename.pdf";
journalViewModel.UserId = 1;
journalViewModel.File = mockFile; // Add simulated file
Mock.Arrange(() => journalRepository.DeleteJournal(null)).Returns(new OperationStatus
{
Status = true
});
// Act
PublisherController controller = new PublisherController(journalRepository, membershipRepository);
RedirectToRouteResult result = controller.Delete(journalViewModel) as RedirectToRouteResult;
// Assert
Assert.AreEqual(result.RouteValues["Action"], "Index");
}
Problema 1 - Exceção de mapeamento:
Sempre que executo meu teste, recebo a seguinte exceção:
Nome do teste: Teste Delete_Journal
Nome completo: Journals.Web.Tests.Controllers.PublisherControllerTest.Delete_Journal
Origem do teste: \ Source \ Journals.Web.Tests \ Controllers \ PublisherControllerTest.cs: linha 132
Resultado do teste: Falha no teste Duração: 0: 00: 00,3822468
Resultado StackTrace: em Journals.Web.Controllers.PublisherController.Delete (diário JournalViewModel) em \ Source \ Journals.Web \ Controllers \ PublisherController.cs: linha 81 em Journals.Web.Tests.Controllers.PublisherControllerTest.Delete_Journal () em \ Source \ Journals.Web.Tests \ Controllers \ PublisherControllerTest.cs: linha 156 Mensagem de resultado: Método de teste Journals.Web.Tests.Controllers.PublisherControllerTest.Delete_Journal lançou a exceção: AutoMapper.AutoMapperMappingException: configuração de mapa de tipo ausente ou mapeamento não suportado.
Tipos de mapeamento: JournalViewModel -> Journal Journals.Model.JournalViewModel -> Journals.Model.Journal
Caminho de destino: Diário
Valor de origem: Journals.Model.JournalViewModel
Parece que há um problema de mapeamento entre as classesJournalViewModel
eJournal
, no entanto, não sei onde é. Eu adicionei este código aoApplication_Start
noGlobal.asax.cs
:
Mapper.CreateMap<Journal, JournalViewModel>();
Mapper.CreateMap<JournalViewModel, Journal>();
E mapeando deJournal
paraJournalViewModel
está funcionando.
No final, tentei adicionarMapper.CreateMap<JournalViewModel, Journal>();
como a primeira linha doDelete
método e, em seguida, tudo funciona, no entanto, não sei por que.
Problema 2 - Exceção HTML
Depois que o mapeamento estiver em execução com a solução alternativa acima, eu tenho um problema no qual a propriedadeStatus
devar opStatus = _journalRepository.DeleteJournal(selectedJournal);
é sempre falso, mesmo que eu tenha usado o Mock para substituí-lo e torná-lo sempre verdadeiro. Isso causa o lançamento de uma exceção HTML que não deve acontecer.
EDITAR
Eu mudei no meu Application_Start para:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Journal, JournalViewModel>();
cfg.CreateMap<JournalViewModel, Journal>();
});
Mas ainda tenho o mesmo erro.
EDIT - Problema 2 resolvido
Acontece que eu esqueci de adicionar o mapeamento à minha classe de teste de unidade, então fiz o seguinte:
[TestInitialize]
public void TestSetup()
{
// Create necessary mappings
Mapper.CreateMap<Journal, JournalViewModel>();
Mapper.CreateMap<JournalViewModel, Journal>();
//...other code omitted for brevity
}
E acontece que essa foi a fonte do problema. Eu acho que, como o Global.asax.cs Application_Start () nunca é chamado nos testes de unidade, o Mapeamento nunca é criado, então eu tive que fazer isso sozinho na inicialização dos testes de unidade.