2013-10-03 5 views
0

У меня есть контроллер MVC 4, который использует метод System.Web.Mvc.HtmlHelper.GenerateLink. Я хочу, чтобы модуль тестировал контроллер, и поэтому я должен издеваться над этим методом. Я использую Moq.Как mock HtmlHelper.GenerateLink

Моя проблема заключается в том, что я получаю исключение NullReferenceException при вызове метода GenerateLink, и я думаю, что это потому, что у меня есть первый параметр (RequestContext), который неправильно высмеивается. Но я не знаю, какие свойства RequestContext я должен высмеивать и как издеваться над этим, чтобы избавиться от этой ошибки.

В настоящее время у меня есть это как установки для издеваться:

var RequestContextMock = new Mock<RequestContext>(); 
RequestContextMock 
    .Setup(x => x.HttpContext.Request.ApplicationPath) 
    .Returns(@"/"); 
RequestContextMock 
    .Setup(x => x.HttpContext.Response.ApplyAppPathModifier(It.IsAny<string>())) 
    .Returns((string s) => s); 

var Routes = new RouteCollection(); 
Routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{id}", 
    defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional}); 

Но что дает NullReferenceException, когда метод GenerateLink выполняется, так ясно, что я пропускаю некоторые значения где-то.

EDIT: Соответствующая часть контроллера при тесте:

public class _AccountInfoController : Controller 
{ 
    readonly IUserRepository _UserRepository; 
    readonly IIdentityRepository _IdentityRepository; 

    public _AccountInfoController(IUserRepository userRepository,IIdentityRepository identityRepository) 
    { 
     this._UserRepository = userRepository; 
     this._IdentityRepository = identityRepository; 
    } 

    [AllowAnonymous] 
    public ActionResult Index(RequestContext requestContext, RouteCollection routes) 
    { 
     var AccountInfoModel = new AccountInfoModel(); 

     string Email = _IdentityRepository.GetEmailAddress(); 
     User User = _UserRepository.GetByEmail(Email); 
     if (User != null) 
     { 
      string Link = HtmlHelper.GenerateLink(requestContext,routes,"Logoff",null,"Index","Logoff",null,null); 

Тест блока является:

[TestMethod] 
    public void HaveTenantNameInModel() 
    { 
     const string TenantName = "tenant name."; 
     Tenant TestTenant = new Tenant {Name = TenantName}; 
     User TestUser = new User {CurrentTenant = (TestTenant)}; 

     var UserRepository = new Mock<IUserRepository>(); 
     UserRepository 
      .Setup(p => p.GetByEmail(null)) 
      .Returns(TestUser); 

     AccountInfoModel AccountInfoModel = new AccountInfoModel();   

     var IdentityRepository = new Mock<IIdentityRepository>(); 

     var ControllerUnderTest = new _AccountInfoController(UserRepository.Object,IdentityRepository.Object); 

     //Mock the request context 
     var RequestContextMock = new Mock<RequestContext>(); 
     RequestContextMock 
      .Setup(x => x.HttpContext.Request.ApplicationPath) 
      .Returns(@"/"); 
     RequestContextMock 
      .Setup(x => x.HttpContext.Response.ApplyAppPathModifier(It.IsAny<string>())) 
      .Returns((string s) => s); 

     var Routes = new RouteCollection(); 
     Routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional}); 

     dynamic Result = ControllerUnderTest.Index(RequestContextMock.Object, Routes); 

     Assert.IsTrue(Result.GetType() == typeof(PartialViewResult)); 
     Assert.AreEqual(TenantName, Result.Model.TenantName); 
    } 
+0

Возможный дубликат: [Тестирование HtmlHelpers в ASP.NET MVC] (http://stackoverflow.com/questions/271699/testing-htmlhelpers-in-asp-net-mvc). –

+0

Пробовал ли вы контутировать контекст контроллера? Хорошо, если вы можете опубликовать Системный тест, а также полный модульный тест. V ar stubContext = new Mock (); и sut.ControllerContext = stubContext.Object – Spock

+0

Привет, Радж, я опубликовал тест модуля и тестируемый контроллер. Я не уверен, почему и как заглушить контекст контроллера. Это то же самое, что и RequestContext, который я использую в качестве параметра для действия индекса? – RHAD

ответ

1

Кажется, вы получаете нулевое ссылочное исключение, потому что ваш маршрут установка данных отсутствует.

в тесте единицы только до вызова системы UnderTest (вар ControllerUnderTest = новый _AccountInfoController (....), добавьте строку

RequestContextMock.SetupGet(x => x.RouteData).Returns(new RouteData()); 

Ниже приводится обновленная версия теста.

[TestMethod] 
    public void Index_WhenActionExecutes_EnsureReturnModelHasExpectedTenantName() 
    { 
     const string expectedTensntName = "tenant name."; 
     var fakeTenant = new Tenant { Name = expectedTensntName }; 
     var fakeUser = new User { CurrentTenant = (fakeTenant) }; 

     var userRepositoryStub = new Mock<IUserRepository>(); 
     userRepositoryStub.Setup(p => p.GetByEmail(It.IsAny<string>())).Returns(fakeUser); 

     var identityRepositoryStub = new Mock<IIdentityRepository>(); 
     var sut = new AccountInfoController(userRepositoryStub.Object, identityRepositoryStub.Object); 

     var requestContextStub = new Mock<RequestContext>(); 
     requestContextStub.Setup(x => x.HttpContext.Request.ApplicationPath).Returns(@"/"); 
     requestContextStub.Setup(x => x.HttpContext.Response.ApplyAppPathModifier(It.IsAny<string>())) 
      .Returns((string s) => s); 

     var fakeRoutes = new RouteCollection(); 
     fakeRoutes.MapRoute(name: "Default", url: "{controller}/{action}/{id}", 
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }); 

     requestContextStub.SetupGet(x => x.RouteData).Returns(new RouteData()); 

     var result = sut.Index(requestContextStub.Object, fakeRoutes) as PartialViewResult; 

     Assert.AreEqual(expectedTensntName, ((AccountInfoModel)result.Model).TenantName); 
    } 
+0

Спасибо, Радж, это прекрасно работает, я провел дни в этом. А также благодарю вас за внесение исправления для именования переменных и т. Д. Я понял, что мои не были правильно названы, и что мне нужно много узнать об модульном тестировании. – RHAD