2016-10-04 22 views
1

これがなぜ失敗しているのか誰かが説明できますか?私は、User.Identity.Nameと何か関係があることを追跡していると思います。それは "Act"で失敗し、System.NullReferenceExceptionが発生します。しかし、同じコントローラ内の別のメソッドが機能します。MOQユニットテストに失敗しました - ASP.NET MVC

作業TEST

[TestMethod] 
public void Home_Index_Returns_ActionResult() 
{ 
    //Arrange 
    var mockRepository1 = new Mock<IEditDataRepository>(); 
    var mockRepository2 = new Mock<IIdentityRepository>(); 

    mockRepository1 
      .Setup(x => x.Edit(It.IsAny<UTCFormViewModel>(), It.IsAny<string>())); 
    HomeController controller = new HomeController(mockRepository1.Object, mockRepository2.Object); 

    //Act 
    ActionResult result = controller.Index(); 

    //Assert 
    Assert.IsInstanceOfType(result, typeof(ActionResult)); 
} 

(別法)TESTを動作しない

[TestMethod] 
public void Edit_Method_Test() 
{ 
    //Arrange 
    var mockRepository1 = new Mock<IEditDataRepository>(); 
    var mockRepository2 = new Mock<IIdentityRepository>(); 

    mockRepository1 
     .Setup(x => x.Edit(It.IsAny<UTCFormViewModel>(), It.IsAny<string>())); 

    HomeController controller = new HomeController(mockRepository1.Object, mockRepository2.Object); 

    //Act (Fails Here) 
    controller.Edit(It.IsAny<UTCFormViewModel>()); 

    //Assert 
    mockRepository1.VerifyAll(); 
    mockRepository2.VerifyAll(); 
} 

CONTROLLER

namespace UTC.Controllers 
{ 
    [Authorize] 
    public class HomeController : Controller  
    { 
     private IEditDataRepository _editDataRepository; 
     private IIdentityRepository _identityRepository; 

     public HomeController(IEditDataRepository editDataRepository, IIdentityRepository identityRepository) 
     { 
      _editDataRepository = editDataRepository; 
      _identityRepository = identityRepository; 
     } 

     public ActionResult Index() 
     { 
      return View(); 
     } 

     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Edit([Bind(Include = "Field1, Field2")] UTCFormViewModel model) 
     { 
      if (ModelState.IsValid) 
      { 
       string fullWindowsUser = User.Identity.Name; 
       string windowsUser = _identityRepository.GetWindowsUser(fullWindowsUser); 

       _editDataRepository.Edit(model, windowsUser); 
       return new HttpStatusCodeResult(HttpStatusCode.OK); 
      } 
      else 
      { 
       throw new HttpException(400, "ModelState Invalid"); 
      } 
     } 
    }  
} 

リポジトリ

namespace UTC.Repositories 
{ 
    public class IdentityRepository : IIdentityRepository 
    { 
     public string GetWindowsUser(string fullWindowsUser) 
     { 
      //Strip off the domain and lower text 
      var windowsUser = fullWindowsUser.ToString().ToLower().Split('\\')[1]; 

      return windowsUser; 
     } 
    } 
} 

リポジトリ

namespace UTC.Repositories 
{ 
    public class EditDataRepository : IEditDataRepository 
    { 
     private UTCEntities db = new UTCEntities(); 

     public void Edit(UTCFormViewModel model, string windowsUser) 
     { 
      db.ustp_UTCUpdate(windowsUser, model.Field1, model.Field2) 

     ); 
    }   
} 
+0

スタックトレースが何を言っていますを設定する必要があるでしょうか? – Rik

+0

"System.NullReferenceException:オブジェクト参照がオブジェクトのインスタンスに設定されていません。" – madvora

+0

これは例外の "メッセージ"です。例外には "stacktrace"もあります。これはコントローラで発生した正確な行を示します。テストをデバッグして検査します。 – Rik

答えて

1

あなたはUser.Identity.Nameにアクセスしているが、コントローラのUserプロパティが

にアクセスしたとき、それはnullになりますので、あなたの試験方法でセットアップではなかったですダミーのユーザーアカウントでコントローラーコンテキストを設定する必要があります。ここでは、ユーザープリンシパルを取得するために必要なHttpContextを偽装するために使用できるヘルパークラスを示します。あなたのテストで

private class MockHttpContext : HttpContextBase { 
    private readonly IPrincipal user; 

    public MockHttpContext(string username, string[] roles = null) { 
     var identity = new GenericIdentity(username); 
     var principal = new GenericPrincipal(identity, roles ?? new string[] { }); 
     user = principal; 
    } 

    public override IPrincipal User { 
     get { 
      return user; 
     } 
     set { 
      base.User = value; 
     } 
    } 
} 

ターゲットコントローラを初期化した後、あなたは、コントローラコンテキスト

//...other code removed for brevity 

var controller = new HomeController(mockRepository1.Object, mockRepository2.Object); 

controller.ControllerContext = new ControllerContext { 
    Controller = controller, 
    HttpContext = new MockHttpContext("[email protected]") 
}; 

//...other code removed for brevity 
+0

ありがとうございました。私はショットを与え、それがどのように進むのかを教えてあげます。 1つの質問ですが、そのヘルパークラスはどこに配置しますか? – madvora

+0

テストプロジェクトで – Nkosi

+0

素晴らしい作品!優秀!ありがとうございました。 – madvora

関連する問題