Тестирование модуля на контроллере, использующем AutoMapper - программирование
Подтвердить что ты не робот

Тестирование модуля на контроллере, использующем AutoMapper

Я пытаюсь использовать unit test контроллер UpdateUser, который использует AutoMapping. Вот код для контроллера

UpdateUserController

    private readonly IUnitOfWork _unitOfWork;
    private readonly IWebSecurity _webSecurity;
    private readonly IOAuthWebSecurity _oAuthWebSecurity;
    private readonly IMapper _mapper;

    public AccountController()
    {
        _unitOfWork = new UnitOfWork();
        _webSecurity = new WebSecurityWrapper();
        _oAuthWebSecurity = new OAuthWebSecurityWrapper();
        _mapper = new MapperWrapper();
    }

    public AccountController(IUnitOfWork unitOfWork, IWebSecurity webSecurity, IOAuthWebSecurity oAuthWebSecurity, IMapper mapper)
    {
        _unitOfWork = unitOfWork;
        _webSecurity = webSecurity;
        _oAuthWebSecurity = oAuthWebSecurity;
        _mapper = mapper;
    }

    //
    // Post: /Account/UpdateUser
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult UpdateUser(UpdateUserModel model)
    {
        if (ModelState.IsValid)
        {
            // Attempt to register the user
            try
            {
                var userToUpdate = _unitOfWork.UserRepository.GetByID(_webSecurity.CurrentUserId);
                var mappedModel = _mapper.Map(model, userToUpdate);

 **mappedModel will return null when run in test but fine otherwise (e.g. debug)**


                _unitOfWork.UserRepository.Update(mappedModel);
                _unitOfWork.Save();

                return RedirectToAction("Index", "Home");
            }
            catch (MembershipCreateUserException e)
            {
                ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
            }
        }
        return View(model);
    }

и это мой Unit Test UpdateUserControllerTest

[Fact]
    public void UserRepository_Update_User_Success()
    {
        Controller = new AccountController(UnitOfWork, WebSecurity.Object, OAuthWebSecurity.Object, Mapper);
        const string emailAsUserName = "[email protected]";
        const string password = "password";
        const string email = "[email protected]";
        const string emailNew = "[email protected]";
        const string firstName = "first name";
        const string firstNameNew = "new first name";
        const string lastName = "last name";
        const string lastNameNew = "new last name";

        var updatedUser = new User
            {
                Email = emailNew,
                FirstName = firstNameNew,
                LastName = lastNameNew,
                UserName = emailAsUserName
            };

        WebSecurity.Setup(
            s =>
            s.CreateUserAndAccount(emailAsUserName, password,
                                   new { FirstName = firstName, LastName = lastName, Email = email }, false))
                   .Returns(emailAsUserName);
        updatedUser.UserId = WebSecurity.Object.CurrentUserId;

        UnitOfWork.UserRepository.Update(updatedUser);
        UnitOfWork.Save();

        var actualUser = UnitOfWork.UserRepository.GetByID(updatedUser.UserId);
        Assert.Equal(updatedUser, actualUser);

        var model = new UpdateUserModel
            {
                Email = emailAsUserName,
                ConfirmEmail = emailAsUserName,
                FirstName = firstName,
                LastName = lastName
            };
        var result = Controller.UpdateUser(model) as RedirectToRouteResult;
        Assert.NotNull(result);
    }

У меня есть ощущение, что при запуске в тестовом режиме картипер не смотрит на конфигурацию сопоставления, которую я установил в Global.asax. Поскольку ошибка возникает только во время выполнения unit test, но не при запуске веб-сайта как есть. Я создал интерфейс IMappaer как DI, поэтому я могу издеваться над ним в целях тестирования. Я использовал Moq для Mocking и xUnit в качестве тестовой среды, я также установил AutoMoq, который я еще не использовал. Есть идеи? Спасибо, что посмотрели мой длинный пост. Надеюсь, кто-то может помочь, часами царапает мне голову и читает много сообщений.

4b9b3361

Ответ 1

В вашем тесте вам нужно создать издеваемую версию вашего интерфейса IMapper, иначе вы не будете тестировать устройство, вы будете интеграционным тестированием. Тогда вам просто нужно сделать простой mockMapper.Setup(m => m.Map(something, somethingElse)).Returns(anotherThing).

Если вы хотите использовать реальную реализацию AutoMapper в своих тестах, вам нужно сначала настроить ее. Ваши тесты автоматически не подберут ваш Global.asax, вам также придется настраивать сопоставления в тестах. Когда я тестирую интеграцию, у меня обычно есть статический метод AutoMapperConfiguration.Configure(), который я вызываю в настройке тестового устройства. Для NUnit это метод [TestFixtureSetUp], я думаю, что для xUnit вы просто поместите его в конструктор.