3

I am using Moq to make automated tests in my .net core 2 app. We use bearer authentication and need to be able to pull out the name from the HttpContext object to make sure we have the right user:

var userName = HttpContext.User.Identity.Name;

I have found tons of examples using System.Web but none that let me mockup a Core 2 setup.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
David
  • 2,173
  • 3
  • 25
  • 36

2 Answers2

8

You can achieve the same thing without having to mock anything and use the already existing classes provided by the framework.

public class ContextHelper {
    public static HttpContext GetHttpContext(string name = "validemail@test.com") {
        var identity = new GenericIdentity(name, "test");
        var contextUser = new ClaimsPrincipal(identity);
        var httpContext = new DefaultHttpContext() {
            User = contextUser
        };
        return httpContext;
    }
}

just because we have the ability to mock certain things does not mean that we have to mock most of the times.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 2
    I like the cleanliness here. My answer, I believe, would allow you to mock up other pieces of the Context object, but for my needs, this is perfect. Thanks! – David Jul 31 '18 at 23:03
4

Ok, so after cobbling together help from a few older links (i.e. Setting HttpContext.Current.Session in a unit test) I was able to get this working, thought I would post it here for posterity:

public class ContextHelper
{
    public static HttpContext GetMockedHttpContext()
    {
        var context = new Mock<HttpContext>();
        var identity = new Mock<IIdentity>();
        var contextUser = new Mock<ClaimsPrincipal>();
        contextUser.Setup(ctx => ctx.Identity).Returns(identity.Object);
        identity.Setup(id => id.IsAuthenticated).Returns(true);
        identity.Setup(id => id.Name).Returns("validemail@test.com");
        context.Setup(x => x.User).Returns(contextUser.Object);

        return context.Object;
    }
}

This allows my unit tests to pull out the user name of my fake user easily.

I call it like this:

var uc = new UserController();
uc.ControllerContext.HttpContext = ContextHelper.GetMockedHttpContext();
uc.WhateverMethodGoesHere();
David
  • 2,173
  • 3
  • 25
  • 36