Writing Unit Test for methods that use User.Identity.Name in ASP.NET Web API

I am writing test cases using the Unit Test for ASP.NET Web API.

Now I have an action which makes a call to some method I have defined in the service layer, where I have used the following line of code.

string username = User.Identity.Name;
// do something with username
// return something

Now how to I create unit test method for this, I am getting null reference exceptions. I am kinda new to writing unit test and stuff.

I want to use Unit Test only for this. Please help me out on this.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The below one is only one way of doing this:

public class FooController : ApiController {

    public string Get() {

        return User.Identity.Name;
    }
}

public class FooTest {

    [Fact]
    public void Foo() {

        var identity = new GenericIdentity("tugberk");
        Thread.CurrentPrincipal = new GenericPrincipal(identity, null);
        var controller = new FooController();

        Assert.Equal(controller.Get(), identity.Name);
    }
}

Method 2

Here’s another way I found in the NerdDinner testing tutorial. It worked in my case:

DinnersController CreateDinnersControllerAs(string userName)
{

    var mock = new Mock<ControllerContext>();
    mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
    mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

    var controller = CreateDinnersController();
    controller.ControllerContext = mock.Object;

    return controller;
}

[TestMethod]
public void EditAction_Should_Return_EditView_When_ValidOwner()
{

    // Arrange
    var controller = CreateDinnersControllerAs("SomeUser");

    // Act
    var result = controller.Edit(1) as ViewResult;

    // Assert
    Assert.IsInstanceOfType(result.ViewData.Model, typeof(DinnerFormViewModel));
}

Make sure you read the full section: Mocking the User.Identity.Name property

It uses the Moq mocking framework that you can install in your Test project using NuGet: http://nuget.org/packages/moq

Method 3

With WebApi 5.0 this is slightly different. You can now do:

controller.User = new ClaimsPrincipal(
  new GenericPrincipal(new GenericIdentity("user"), null));

Method 4

None of this ended up working for me, I used the solution on another question which uses Moq to set up a user name in the ControllerContext: https://stackoverflow.com/a/6752924/347455

Method 5

This is my solution.

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, "Nikita"),
    new Claim(ClaimTypes.NameIdentifier, "1")
};

var identity = new ClaimsIdentity(claims);
IPrincipal user = new ClaimsPrincipal(identity);

controller.User = user;

Method 6

Here i found the solution for another way that how to set the user identity name for the controller level testing from the test method.

public static void SetUserIdentityName(string userId)
        {
            IPrincipal principal = null;
            principal = new GenericPrincipal(new GenericIdentity(userId), 
            new string[0]);
            Thread.CurrentPrincipal = principal;
            if (HttpContext.Current != null)
            {
                HttpContext.Current.User = principal;
            }
        }

Method 7

When I run Unit test – in my case it uses Windows authentication and Identity.Name is my domain name, which I also want to change for the test.
So I use such approach with ‘hacking’ things I want in IAuthenticationFilter

Method 8

If you have lots of Controllers to Test then I Would Suggest to create a base class and in the constructor create a GenericIdentity & GenericPrincipal and set Thread.CurrentPrincipal

GenericPrincipal principal = new GenericPrincipal(new 
    GenericIdentity("UserName"),null); Thread.CurrentPrincipal = principal;

Then Inherit that class .. So that way every Unit Test class will have Principle Object Set

[TestClass]
public class BaseUnitTest
{
    public BaseUnitTest()
    {
      GenericPrincipal principal = new GenericPrincipal(new GenericIdentity("UserName"),null);   
      Thread.CurrentPrincipal = principal;
    }
}


[TestClass]
public class AdminUnitTest : BaseUnitTest
{
   [TestMethod]
   public void Admin_Application_GetAppliction()
   {
   }
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x