6

I'm attempting to test a controller method that utilizes JWT claims to get the user name of the client like so:

[Authorize]
[Route("api/[controller]")]
public class ApprovalsController : Controller
{
  // POST api/approvals
    [HttpPost]
    public IActionResult Post([FromBody]ApprovalViewModel value)
    {
        // ...

        // Incoming approval VM converted here
        Approval newApproval = TinyMapper.Map<Approval>(value);

        // Values set server-side here.
        newApproval.Id = -1;
        newApproval.Created = DateTime.Now;

        // Claim queried here
        newApproval.CreatedBy = User.FindFirst(ClaimTypes.Name).Value; 

        // Submission to context
        _approvalRepo.Insert(newApproval);
        _approvalRepo.Update();

        // ...
    }

But I've had the darnedest luck in trying to conceive of a way to unit test the above controller using Moq and XUnit. Many of the questions I've searched for involve directly setting the ControllerBase.User attribute of the controller, but in Aspnetcore.MVC (1.1.1), User has been set as read-only.

What is it that I'm to do, here?

D Owrey
  • 63
  • 2
  • 5
  • 2
    @Nkosi For self-education purposes, could you explain why this question is *exactly* the same as the one linked? There is a similarity, but Ilya's answer is direct and simple, which I see as meritorious. – D Owrey Apr 17 '17 at 05:33

1 Answers1

9

Controller.User is just a wrapper of Controller.ControllerContext.HttpContext.User. Mock any context first:

var controller = new HomeController();

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

controller.ControllerContext.HttpContext = contextMock.Object;

Assert.NotNull(controller.User);
Ilya Chumakov
  • 23,161
  • 9
  • 86
  • 114
  • Don't know if it due to a recent change in .NET or not, but the `HttpContext` is now expecting a `HttpContextBase`. Just thought I'd mention it. – Thierry Dec 02 '18 at 03:09