2016-05-25 7 views
0

Я пытаюсь написать единичный тест для тестирования моего контроллера, который использует сеанс. Я понимаю концепцию, что httpcontext генерируется только из запроса, который находится в браузере, и после вызова тестового модуля Unit test, текущий контекст будет null.Сеансы тестирования модулей все еще возвращают null после Mocking

Я попытался решить эту проблему на основе первой части этой статьи http://www.dontpaniclabs.com/blog/post/2011/03/22/testing-session-in-mvc-in-four-lines-of-code/, но она по-прежнему не работает для меня. См. Мой код ниже.

[TestFixtureSetUp] 
    public void Configure_AutoMapper() 
    { 
     _product = new ProductViewModel() 
     { 
      Id = Guid.NewGuid(), 
      Category = Guid.Parse("72E42A11-DFA4-4AB9-A735-5CD5C18396D4"), 
      Brand = Guid.Parse("96E68B67-60FB-4531-898E-815433B44D89"), 
      Description = "From test", 
      CostPrice = Parse("17.00"), 
      SalePrice = Parse("25.00"), 
      Quantity = 7, 
      BusinessId = Guid.Parse("BDF9FB7F-DB40-4365-9872-AECD616ED415") 
     }; 

     var context = new Mock<ControllerContext>(); 
     var session = new Mock<HttpSessionStateBase>(); 
     context.Setup(m => m.HttpContext.Session).Returns(session.Object); 
     _productsController = new ProductsController {ControllerContext = context.Object}; 

     var userSessionInfo = new UserSessionViewModel() 
     { 
      FirstName = "Junior", 
      LastName = "Labolz", 
      BusinessId = Guid.Parse("BDF9FB7F-DB40-4365-9872-AECD616ED415") 
     }; 

     SessionHelper.AddUserDetailsToSession(SessionHelper.UserDetails, userSessionInfo); 
    } 


    [Test] 
    public void Display_Products_List_On_View_Products_Button_Click() 
    { 
     //Set Up 

     //Act 
     var viewResult = (ViewResult)_productsController.Index(); 

     //Assert 
     Assert.That(string.Empty, Is.EqualTo(viewResult.ViewName)); 
    } 


    public static void AddUserDetailsToSession(string sessionName, UserSessionViewModel userSessionDetails) 
    { 
     HttpContext.Current.Session.Add(sessionName, userSessionDetails); 
    } 

** На основании ответа Ричарда я изменил его на **

 var context = new Mock<ControllerContext>(); 
     var session = new Mock<HttpSessionStateBase>(); 
     context.Setup(m => m.HttpContext.Session).Returns(session.Object); 
     var userSessionInfo = new UserSessionViewModel() 
     { 
      FirstName = "Junior", 
      LastName = "Labolz", 
      BusinessId = Guid.Parse("BDF9FB7F-DB40-4365-9872-AECD616ED415") 
     }; 
     context.Object.HttpContext.AddUserDetailsToSession(SessionHelper.UserDetails, userSessionInfo); 

     _productsController = new ProductsController {ControllerContext = context.Object}; 

конструктор контроллера продукта

public ProductsController() 
    { 
     _productService = new ProductServiceClient(); 
     _userSessionViewModel = (UserSessionViewModel)SessionHelper.GetSessionDetail(SessionHelper.UserDetails); 
    } 

Получить метод Session

public static object GetSessionDetail(string sessionName) 
    { 
     return HttpContext.Current.Session[sessionName]; 
    } 

ответ

0

Я вижу, что ваш код содержит статическую функцию, которая напрямую ссылается на HttpContext.Current. Вы не можете сделать это, если хотите выполнить единичный тест, вместо этого вы должны работать с инъецированными экземплярами HttpContextBase.

В ваших модульных тестах эти экземпляры будут вашим фокусом. В процессе производства вы настроили свой контейнер, чтобы ввести HttpContext.Current, когда запрашивается HttpContextBase.

Я хотел бы переписать статический метод быть метод расширения:

public static void AddUserDetailsToSession(this HttpContextBase context, 
    string sessionName, UserSessionViewModel userSessionDetails) 
{ 
    context.Session.Add(sessionName, userSessionDetails); 
} 

Затем вызовите его из теста:

context.Object.AddUserDetailsToSession(SessionHelper.UserDetails, userSessionInfo); 
+0

я все еще получаю нулевой ссылочный исключение, может быть, потому что я тоже пытаясь прочитать сеанс в моем конструкторе productController? –

+0

Я обновил свой код, пожалуйста, ищите меня. Я изменил его, чтобы использовать метод расширения, у меня есть заголовок в моем обновлении «на основе ответа Ричарда». Я также показываю вам, что у меня есть в контроллере продукта. –

+0

Вы не можете использовать HttpContext.Current в любом месте - вы можете получить HttpContext из ControllerContext. В любом случае вы не должны получать доступ к Session из конструктора контроллера, так как у вас нет контекста в точке, которую вы вызываете. – Richard

 Смежные вопросы

  • Нет связанных вопросов^_^