Click here to Skip to main content
15,889,116 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I need help with Mocking on Unit Tests.

I am trying to call a method in a WebApi Controller that has the Authorization attribute on it, for example

C#
[Authorize]
[HttpGet]
[ActionName("FineOutcome")]
[ProducesResponseType(typeof(Response), 200)]
[ProducesResponseType(401)]
public async Task<IActionResult> FineOutcome(string PCN, int ia)
{
  //Code Action here
}


The authorisation is handled by a JWT Bearer Token. Now I am trying to Test this method and can't / don't know how to mock or pass in the JWT bearer token.

What I have tried:

C#
var userMock = new Mock<IPrincipal>();
userMock.Setup(p => p.IsInRole("admin")).Returns(true);

var contextMock = new Mock<HttpContext>();
contextMock.Setup(x => x.User ).Returns(new ClaimsPrincipal());

controller.ControllerContext.HttpContext = contextMock.Object;
var outcome = controller.FineOutcome("513073/372796", 467);


but when I try to get execute the test it controller method complains that the user is blank. Can anyone give me a point in the right direction.

Links I've tried

c# - How to mock Controller.User using moq - Stack Overflow[^]
c# - Unit Testing a JWT Token with Web API - Stack Overflow[^]
Posted
Updated 2-Oct-21 3:27am

1 solution

Unit tests are for testing your code and mocking is for replacing the parts of the functionality that are provided by third-parties that don't work in your testing environment (HttpContext being a good example, your unit tests are not running in the context of a web site), or that you need to control the outcomes from.

So long story short you trying to make the authorise attribute work is you testing the underlying asp.net framework, but you should assume that Microsoft have already tested that and that it works, so you should instead focus on testing your code.

If your code is getting the user from some form of httpcontext that that is your actual problem; getting back to what I've said above your unit tests should not rely on environmental things such as contexts, sessions, databases, networks etc, your tests need to run self-contained and in isolation. Change your code such that it gets the user via some sort of service class that you inject into the controller, and your unit test will then mock that service to provide a hard-coded user, however when the code is working on the real site the controller will have a proper user service injected that gets the user from the httpcontext, or wherever it currently gets it from.
 
Share this answer
 
Comments
Simon_Whale 21-Feb-19 10:15am    
Thanks F-ES Sitecore.

What I am trying to do is ensure that after my unit tests have run I can run a integration / service test to ensure that they all work together happily as a co-worker did some refactors the unit tests worked successfully but it didn't work when the site was run in its entirety.
F-ES Sitecore 21-Feb-19 10:17am    
You don't use unit testing for that, you have a different set of tests for integration.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900