Я создаю несколько модульных тестов для моего класса ASP .NET MVC контроллер, и я столкнулся с некоторыми очень странные ошибки:Проблемы создания модульного тестирования для ASP .NET MVC
Мой код контроллер находится ниже:
[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");
}
Мой тестовый код ниже:
[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");
}
Задача 1 - Mapping Исключение:
Каждый раз, когда я запускаю мой тест я получаю следующее исключение:
Имя теста: Delete_Journal Тест
FullName: Journals.Web.Tests.Controllers.PublisherControllerTest.Delete_Journal
Test Источник: \ Source \ Журналы .Web.Tests \ Контроллеры \ PublisherControllerTest.cs : линия 132
Тест Результат: Failed Test Продолжительность: 0: 00: 00,3822468Результат StackTrace: в Journals.Web.Controllers.PublisherController.Delete (J ournalViewModel журнал) в \ Source \ Journals.Web \ Контроллеры \ PublisherController.cs: строка 81 в Journals.Web.Tests.Controllers.PublisherControllerTest.Delete_Journal() в \ Source \ Journals.Web.Tests \ Контроллеры \ PublisherControllerTest.cs: линия 156 Результат сообщение: метод испытания Journals.Web.Tests.Controllers.PublisherControllerTest.Delete_Journal бросил исключение: AutoMapper.AutoMapperMappingException: Отсутствует тип конфигурации карта или не поддерживается отображение.
типы карт: JournalViewModel -> Журнал Journals.Model.JournalViewModel -> Journals.Model.Journal
назначения Путь: Журнал
Источник значение: Journals.Model.JournalViewModel
Кажется, что существует проблема сопоставления между классами JournalViewModel
и Journal
, однако я не знаю, где это. Я добавил этот код на Application_Start
в Global.asax.cs
:
Mapper.CreateMap<Journal, JournalViewModel>();
Mapper.CreateMap<JournalViewModel, Journal>();
и отображение Journal
в JournalViewModel
работает.
В конце я попытался добавить Mapper.CreateMap<JournalViewModel, Journal>();
в качестве первой строки метода Delete
, а затем все работает, однако я не знаю, почему.
Задача 2 - HTML Исключение
После того, как отображение работает с выше обходным путем, у меня есть проблема, в которой свойство Status
из var opStatus = _journalRepository.DeleteJournal(selectedJournal);
всегда ложно, даже если я использовал Mock, чтобы переопределить его и сделать это всегда так. Это вызывает выброс HTML Exception, которого не должно произойти.
EDIT
Я изменил в моей Application_Start на:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Journal, JournalViewModel>();
cfg.CreateMap<JournalViewModel, Journal>();
});
Но я до сих пор ту же ошибку.
EDIT - Проблема 2 решаемые
Оказывается, что я забыл добавить отображение на мой модульного тестирования класса, поэтому я сделал следующее:
[TestInitialize]
public void TestSetup()
{
// Create necessary mappings
Mapper.CreateMap<Journal, JournalViewModel>();
Mapper.CreateMap<JournalViewModel, Journal>();
//...other code omitted for brevity
}
И получается, что это был источником проблемы. Я думаю, что поскольку приложение Global.asax.cs Application_Start() никогда не вызывается в модульных тестах, сопоставление никогда не создается, поэтому я должен был сделать это сам в инициализации модульных тестов.
Вы, наверное, нужна какая-то 'TestBase' класс wh если вы вызываете свой код конфигурации отображения. Статический «Mapper» в вашем тесте ничего не знает о конфигурации сопоставления из вашего «Global.asax.cs». –
Я бы предложил использовать статический метод для создания всех карт, а затем вызвать этот статический метод как часть вашей тестовой настройки. Что касается второй проблемы, не могли бы вы сообщить мне, что такое JournalRepository. Вы передаете это как зависимость? –
Какую версию Automapper вы используете?Я бы предложил использовать абстракции («IMapper») вместо статического API, поскольку вы уже обнаружили трудности при тестировании статических API-модулей – Nkosi