2016-10-04 85 views
1

有人可以請幫忙解釋爲什麼這是失敗?我想我可能會跟蹤它與User.Identity.Name有關。它在「Act」失敗,我得到一個System.NullReferenceException。但是在同一個控制器中的另一種方法確實有效最小單元測試失敗 - ASP.NET MVC

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

NOT WORKING 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"); 
      } 
     } 
    }  
} 

REPOSITORY

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

REPOSITORY

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

這就是異常的」消息「。該例外還有一個「堆棧跟蹤」,它會告訴你在控制器中發生的確切位置。調試測試以檢查它。 – Rik

回答

1

您正在訪問User.Identity.Name但控制器的User財產是不是在您的測試方法的設置,因此訪問

時,這將是空您將需要使用虛擬用戶帳戶來設置控制器上下文。這裏有一個助手類,可以用來模擬獲取用戶主體所需的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

非常感謝。我會給你一個鏡頭,讓你知道它是怎麼回事。但有一個問題,你會在哪裏放置該助手類? – madvora

+0

在測試項目 – Nkosi

+0

作品太棒了!優秀!謝謝。 – madvora