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
Return/Consume Dynamic Anonymous Type Across Assembly Boundaries
Elevating Privileges Doesn't Work with Useshellexecute=False
Resharper Warning - Access to Modified Closure
An Object Reference Is Required for the Non-Static Field, Method, or Property
Why Must We Define Both == and != in C#
Struggling Trying to Get Cookie Out of Response with Httpclient in .Net 4.5
What Is a Good Unique Pc Identifier
Iis Wcf Service Hosting VS Windows Service
How to Give Read/Write Permissions to a Folder During Installation Using .Net
How to Get a List of Keys from JSON.Net
Linq Group by Multiple Fields -Syntax Help
Line Intersection with Aabb Rectangle
How to Communicate with a Windows Service
How to Display a File's Properties Dialog from C#
Using Mediaelement to Play Video from Stream