2016-10-04 2 views
1

Может кто-нибудь помочь, чтобы объяснить, почему это не удается? Я думаю, что я мог бы отследить его до того, чтобы иметь какое-то отношение к User.Identity.Name. Он не работает в «Act», и я получаю исключение System.NullReferenceException. Однако другой метод в одном контроллере работает.Ошибка тестирования модуля MOQ - ASP.NET MVC

Дрессировка

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

НЕ Дрессировка (по другому методу)

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

КОНТРОЛЛЕР

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 свойство контроллера не была установка в вашем методе испытаний, следовательно, он будет нулевым, когда доступ к

вам нужно будет установить контекст контроллера с помощью фиктивной учетной записи пользователя. Вот вспомогательный класс, который вы можете использовать, чтобы высмеять 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