Mock Httpcontext for Unit Testing a .Net Core MVC Controller

Mock HttpContext for unit testing a .NET core MVC controller?

I was able to initialize the httpcontext and header in this way:

[TestMethod]
public void TestValuesController()
{
ValuesController controller = new ValuesController();
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
controller.ControllerContext.HttpContext.Request.Headers["device-id"] = "20317";
var result = controller.Get();
//the controller correctly receives the http header key value pair device-id:20317
...
}

How to moq HttpContext on Asp net Core

You can use ControllerContext to set the context to be DefaultHttpContext which you can modify to your needs.

var ctx = new ControllerContext() { HttpContext = new DefaultHttpContext()};
var tested = new MyCtrl();
tested.ControllerContext = ctx;

Unit Tests Mock ControllerContext HttpContext No service for type 'Microsoft.AspNetCore.Mvc.View...ITempDataDictionaryFactory' has been registered

i finally, found a solution by mocking the controller TempData

Source: Mocking a TempData in ASP.NET Core in MSTest

var tempData = new Microsoft.AspNetCore.Mvc.ViewFeatures
.TempDataDictionary(httpContext, Mock.Of<Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataProvider>());
tempData["ReturnUrl"] = "";

_sutController.ControllerContext.HttpContext = httpContext;
_sutController.TempData = tempData

Unit Test Controller mocking ISession

If anyone faces the same issue one day, here you go:

public void GetFoos_AllGood_ReturnList()
{
//Arrange
Mock<ISession> sessionMock = new Mock<ISession>();

Web.Controllers.FooController fooController = new Web.Controllers.FooController();
fooController.ControllerContext.HttpContext = new DefaultHttpContext();
fooController.ControllerContext.HttpContext.Request.Headers["Foo"] = 0;
fooController.ControllerContext.HttpContext.Session = sessionMock.Object;

//Act
var result = fooController.GetFoos() as JsonResult;

//Assert
Assert.NotNull(result);
}

How to unit test MVC controller that uses HttpContext in ASP.NET Core 1.1

You can setup a controller with an instance of the DefaultHttpContext like in this helper function.

    public MyController CreateController()
{
var actionContext = new ActionContext
{
HttpContext = new DefaultHttpContext(),
RouteData = new RouteData(),
ActionDescriptor = new ControllerActionDescriptor()
};

var controller = new MyController
{
ControllerContext = new ControllerContext(actionContext)
};

return controller;
}

Then the HttpContext property of the MyController instance is not null anymore and it provides a default AuthenticationManager in the HttpContext.Authentication property.

Mock HttpRequest in ASP.NET Core Controller

When creating an instance of the controller under test, make sure to assign a HttpContext that contains the required dependencies for the test to be exercised to completion.

You could try mocking a HttpContext and providing that to the controller or just use DefaultHttpContext provided by the framework

//Arrange
var mockedAccessor = new Mock<IAccessor>();
//...setup mockedAccessor behavior

//...

var httpContext = new DefaultHttpContext(); // or mock a `HttpContext`
httpContext.Request.Headers["token"] = "fake_token_here"; //Set header
//Controller needs a controller context
var controllerContext = new ControllerContext() {
HttpContext = httpContext,
};
//assign context to controller
var controller = new PlayersController (mockedAccessor.Object){
ControllerContext = controllerContext,
};

//Act
var result = controller.Get();

//...

The above assumes you already know how to mock the controller dependencies like IAccessor and was meant to demonstrate how to provide framework specific dependencies needed for the test.

ASP.NET MVC unit test controller with HttpContext

If you are using Typemock, you can do this:

Isolate.WhenCalled(()=>controller.HttpContext.Current.Session["UserID"])
.WillReturn("your id");

The test code will look like:

[TestMethod]
public void Retrieve_IndexTest()
{
// Arrange
const string expectedViewName = "Index";

IndexController controller = new IndexController();
Isolate.WhenCalled(()=>controller.HttpContext.Current.Session["UserID"])
.WillReturn("your id");
// Act
var result = controller.Index() as ViewResult;

// Assert
Assert.IsNotNull(result, "Should have returned a ViewResult");
Assert.AreEqual(expectedViewName, result.ViewName, "View name should have been {0}", expectedViewName);
}


Related Topics



Leave a reply



Submit