0

Controller.cs

public async Task<IActionResult> BookingRequest(int cid)
{
    string[] requestParams = Request.QueryString.ToString().Split("&");
    BookingVM objSessionBookingVM = new BookingVM();
    var value = HttpContext.Session.GetString("SessionBookingVM");
    if(value!=null)
    {
        //some logic
    }
}

XunitTest.cs

[Fact]
public async Task<IActionResult> BookingRequestTest_ReturnsViewWithSlots()
{
    // Act
    _controller.ControllerContext = new ControllerContext();
    _controller.ControllerContext.HttpContext = new DefaultHttpContext();
    _controller.ControllerContext.HttpContext.Request.Headers["device-id"] = "20317";
    _controller.ControllerContext.HttpContext.Request.QueryString = new QueryString("?cid=11&culture=no");

    var result = await _controller.BookingRequest(mockId);

    // Assert
    var viewResult = Assert.IsType<ViewResult>(result);
    Assert.IsType<BookingVM>(viewResult.ViewData.Model);
    return result;
}

When I run the test, I'm getting the exception at below line

var value = HttpContext.Session.GetString("SessionBookingVM");

The error says session has not been established. I have tried a lot but nothing works. Can anyone help me to fix this out?

Suvethan Nantha
  • 2,404
  • 16
  • 28
  • what have you tried that did not work? mock the session and assign it to the context https://stackoverflow.com/a/47203926/5233410 – Nkosi Sep 28 '18 at 10:03
  • @Nkosi HttpContext.Session is undefined – Suvethan Nantha Sep 28 '18 at 10:14
  • which is why you have to define one and assign it to the property for the test. What behavior is it that you want when that is called? – Nkosi Sep 28 '18 at 10:17
  • @Nkosi can you explain me little bit deep? – Suvethan Nantha Sep 28 '18 at 10:20
  • session does not really exist when running unit test. so you need to mock the session so that the method under test can flow as expected. once mocked you assign it to http context so test does not throw exception – Nkosi Sep 28 '18 at 10:21
  • @Nkosi Can you provide some sample answer? – Suvethan Nantha Sep 28 '18 at 10:27
  • I provided a link before on how to mock the session. – Nkosi Sep 28 '18 at 10:28
  • It does not show the assigning part of httpcontext – Suvethan Nantha Sep 28 '18 at 10:33
  • I told you you just assign it to the session property on the httpcontext. you are already make use of the default http context in your provided example. – Nkosi Sep 28 '18 at 10:34
  • 3
    Controllers aren't generally good candidates for unit tests, since they involve far too many dependencies. Some simple actions can be effectively unit tested, but generally speaking, you're better off doing integration testing with the test server. However, if you insist on doing a unit test, then you must mock *everything*. You provided a mocked `HttpContext`, but you did not mock a session object on that. Therefore, the session object doesn't exist. – Chris Pratt Sep 28 '18 at 12:56
  • 1
    Refactor your code to not use `HttpContext` directly, instead a contract, say `ISessionBookingService` with an implementation that reads session state – andrei.ciprian Nov 06 '18 at 12:47

0 Answers0