2013-05-08 22 views
14

AutoMappingを使用するUpdateUserコントローラをユニットテストしようとしています。ここでは、コントローラAutoMapperを使用するコントローラのユニットテスト

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); 
    } 

ためのコードであり、これは私のユニットテスト 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で設定したマッパー設定を見ません。エラーは単体テストの実行中にのみ発生しますが、Webサイトを実行しているときには発生しません。 DIとしてIMappaerインターフェイスを作成しましたので、テスト目的で偽装することができます。 Moock for MockingとxUnitをテストフレームワークとして使用しましたが、まだ使用していないAutoMoqもインストールしました。何か案が?私の長い投稿を見ていただきありがとうございます。誰かが助けてくれることを願って、何時間も私の頭を掻きとって、たくさんの投稿を読んでください。

答えて

17

テストではIMapperインターフェイスの模擬バージョンを作成する必要があります。それ以外の場合は単体テストではなく、統合テストです。次に、簡単な操作を行うだけですmockMapper.Setup(m => m.Map(something, somethingElse)).Returns(anotherThing)

テストで実際のAutoMapperの実装を使用する場合は、まずそれを設定する必要があります。あなたのテストはあなたのGlobal.asaxを自動的に受け取ることはありませんので、テストでもマッピングを設定する必要があります。私がこのような統合テストをしているとき、私は通常、テストフィクスチャセットアップで呼び出すstatic AutoMapperConfiguration.Configure()メソッドを持っています。 NUnitの場合、これは[TestFixtureSetUp]メソッドです。xUnitではコンストラクタに入れるだけです。

+2

こんにちはアダム、応答ありがとう。私は、私のテストコンストラクタでglobal.asaxで作成したAutoMapperConfiguration.Configure()メソッドを呼び出すことによってそれを修正することができました。 – Steven

+2

[TestFixtureSetUp]メソッドでAutoMapperConfiguration.Configure()を使用すると、これが最善の方法だと思います。 – Tun

+0

私にとっては、オートマッパーとして使用するアセンブリも指定しなければなりませんでした。AutoMapperConfiguration.ConfigureAutoMapper(typeof(someMappingConfig).Assembly) – RandomUs1r

関連する問題