Khaine775
Khaine775

Reputation: 2765

ASP MVC Unit Testing GetUserId()

I have a controller, where I'm calling a userId:

var userId = User.Identity.GetUserId();

This makes my unit test fail, since User is null. I've tried to set a user in the test method using this method, but User is still null in the controller when the test runs.

var context = new Mock<HttpContextBase>();
var mockIdentity = new Mock<IIdentity>();
context.SetupGet(x => x.User.Identity).Returns(mockIdentity.Object);
mockIdentity.Setup(u => u.Name).Returns("test_userName");

Any hints as to what I'm doing wrong?

Upvotes: 1

Views: 1429

Answers (3)

nimeshjm
nimeshjm

Reputation: 1708

You are mocking HttpContextBase but are not passing it to your controller. Try this pattern:

Class:

    public MyClass
    {
        private readonly HttpContextBase _contextBase;

        public MyClass(HttpContextBase contextBase)
        {
            this._contextBase = contextBase;
        }

        public void Process()
        {
            var userId = _contextBase.User.Identity;
        }
    }

Test:

    [Test]
    public void MyClass_Test_SO()
    {
        // arrange
        var context = new Mock<HttpContextBase>();
        var mockIdentity = new Mock<IIdentity>();
        context.SetupGet(x => x.User.Identity).Returns(mockIdentity.Object);
        mockIdentity.Setup(u => u.Name).Returns("test_userName");
        var sut = new MyClass(context.Object);

        // act
        sut.Process();

        // assert
        // ... whatever
    }

Upvotes: 0

Khaine775
Khaine775

Reputation: 2765

Okay, so according to this post, you can do it like this:

public class MyController: Controller
{
    public Func<string> GetUserId; //For testing

    public MyController()
    {
        GetUserId = () => User.Identity.GetUserId();
    }
    //controller actions
}

And then instead of caling User.Identity.GetUserId() when you want the user, you just call GetUserId() and mock out the user id in your test:

controller = new MyController()
{
    GetUserId = () => "IdOfYourChoosing"
};

Upvotes: 0

Muhammad Adeel Zahid
Muhammad Adeel Zahid

Reputation: 17784

The HttpContextBase.User is of type IPrincipal and you have not mocked it. That's why it is returning null when you access it in tests. You can mock it as follows

var controllerContext = new Mock<ControllerContext>();
var principal = new Moq.Mock<IPrincipal>();
principal.Setup(p => p.IsInRole("Administrator")).Returns(true);
principal.SetupGet(x => x.Identity.Name).Returns(userName);
controllerContext.SetupGet(x => x.HttpContext.User).Returns(principal.Object);
controller.ControllerContext = controllerContext.Object;

Here is the reference of this code

Upvotes: 2

Related Questions