Что не так с этим TestMethod? - PullRequest
2 голосов
/ 16 августа 2011

Итак, я хочу немного изучить TDD и хотел посмотреть, смогу ли я протестировать действие Index, которое должно просто возвращать View.

Тест не проходит, и ошибка

Метод теста Summumnet.Tests.Controllers.PhysicalTestsControllerTest.IndexShouldReturnView сгенерировал исключение: System.ArgumentException: выражение не является доступом к свойству: c => c.FindById (1)

Здеськод действия моего контроллера:

[Authorize]
    [AllowedToEditEHR]
    public class PhysicalTestsController : Controller
    {
        private IUnitOfWork unitOfWork;
        private IRepository<EHR> ehrRepository;
        private const int PAGESIZE = 5;


        public PhysicalTestsController(IUnitOfWork unit)
        {
            unitOfWork = unit;
            ehrRepository = unitOfWork.EHRs;

        }

        public ActionResult Index(int ehrId, int? page)
        {
            EHR ehr = ehrRepository.FindById(ehrId);
            var physicaltests = ehr.PhysicalTests.Where(test => !test.IsDeleted).OrderByDescending(test => test.CreationDate);
            List<PhysicalTestListItem> physicalTestsVM = new List<PhysicalTestListItem>();
            Mapper.Map(physicaltests, physicalTestsVM);
            var paginatedTests = physicalTestsVM.ToPagedList(page ?? 0, PAGESIZE);
            return View(paginatedTests);
        }

и вот тест

[TestClass]
    public class PhysicalTestsControllerTest
    {
        [TestMethod]
        public void IndexShouldReturnView()
        {
            // Arrange

            var mock = new Mock<ControllerContext>();
            mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("nacho");
            mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

            var mockUnitofWork = new Mock<IUnitOfWork>();
            var mockEhrRepository = new Mock<IRepository<EHR>>();
            mockEhrRepository.SetupGet(c => c.FindById(1)).Returns(new EHR { PhysicalTests = new List<PhysicalTest>()});
            mockUnitofWork.SetupGet(p=>p.EHRs).Returns(mockEhrRepository.Object);
            PhysicalTestsController controller = new PhysicalTestsController(mockUnitofWork.Object);
            controller.ControllerContext = mock.Object;

            // Act
            ViewResult result = controller.Index(1, 0) as ViewResult;

            // Assert
            Assert.IsNotNull(result);
        }

1 Ответ

8 голосов
/ 16 августа 2011

Несколько указателей:

  1. Вам не нужно высмеивать HttpContext для этого теста.Конечно, у вас есть атрибут Authorize на вашем контроллере, но фильтры действий не запускаются, когда вы тестируете свои контроллеры.Таким образом, вы можете просто предположить, что пользователь будет аутентифицирован и авторизован.

  2. SetupGet, я считаю, довольно устарел.Вместо этого вам следует рассмотреть возможность использования Setup:

    mockUnitofWork.Setup(p => p.EHRs).Returns(mockEhrRepository.Object);
    

    В этом и заключается причина вашей ошибки, поскольку SetupGet можно использовать только для properties , тогда как Setup можетиспользоваться более или менее на чем-либо.Поскольку FindById не является свойством (это метод), вы получаете эту ошибку.

  3. При настройке вызова функции вы обычно получите лучшие результаты, если не дадитеточные входные аргументы, но лучше указать условия, которым должны удовлетворять входные аргументы.Это позволяет избежать неожиданных и часто трудно отслеживаемых ошибок тестирования, когда вы передаете два идентичных - но отдельных - экземпляра класса и ожидаете, что они будут одинаковыми.

    В Moq вы можете использовать статические методына It, чтобы сделать это.Если вы хотите разрешить любой int, просто скажите It.IsAny<int>() вместо целочисленного аргумента.Если вы хотите быть конкретным, вы можете использовать лямбда-выражение, чтобы объявить, когда должно применяться поведение, используя It.Is<int>(i => someCondition(i)).Поэтому вместо .Setup(c => c.FindById(1)) вы говорите

    mockEhrRepository.Setup(r => r.FindById(It.Is<int>(i => i == 1)).Returns(...)
    

    Для типов значений это не имеет значения, но я думаю, что это хорошая привычка.Я обычно не обращаю внимания на , какое целое число дается, что немного упрощает выражение установки:

    mockEhrRepository.Setup(r => r.FindById(It.IsAny<int>()).Returns(...)
    

Но, чтобы быть ясным: ЕдинственноеВ этом сообщении вам нужно , чтобы избавиться от вашей ошибки, - изменить SetupGet на Setup.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...