Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate Asp.net User identity when testing WebApi controllers

I am using Web API 2. In web api controller I have used GetUserId method to generate user id using Asp.net Identity.

I have to write MS unit test for that controller. How can I access user id from test project?

I have attached sample code below.

Web API Controller

public IHttpActionResult SavePlayerLoc(IEnumerable<int> playerLocations)
{
    int userId = RequestContext.Principal.Identity.GetUserId<int>();
    bool isSavePlayerLocSaved = sample.SavePlayerLoc(userId, playerLocations);
    return Ok(isSavePlayerLocSaved );
}

Web API Controller Test class

[TestMethod()]
public void SavePlayerLocTests()
{
    var context = new Mock<HttpContextBase>();
    var mockIdentity = new Mock<IIdentity>();
    context.SetupGet(x => x.User.Identity).Returns(mockIdentity.Object);
    mockIdentity.Setup(x => x.Name).Returns("admin");
    var controller = new TestApiController();
    var actionResult = controller.SavePlayerLoc(GetLocationList());
    var response = actionResult as OkNegotiatedContentResult<IEnumerable<bool>>;
    Assert.IsNotNull(response);
}

I tried using mock method like above. But it is not working. How do I generate Asp.net User identity when I call from test method to controller?

like image 804
Vetri Selvan Avatar asked Jan 11 '17 05:01

Vetri Selvan


People also ask

What is ASP NET identity in Web API?

ASP.NET Core Identity: Is an API that supports user interface (UI) login functionality. Manages users, passwords, profile data, roles, claims, tokens, email confirmation, and more.

What is a best practice when unit testing a controller?

A good way to ensure unit tests is to use test driven development (TDD). For this article, we will take the example of an ExpressJS controller. This is an example of a small MVC packed in one place. We will see how modular design and testing go hand-in-hand and support each other resulting in a well-structure codebase.


1 Answers

If the request is authenticated then the User property should be populated with the same principle

public IHttpActionResult SavePlayerLoc(IEnumerable<int> playerLocations) {
    int userId = User.Identity.GetUserId<int>();
    bool isSavePlayerLocSaved = sample.SavePlayerLoc(userId, playerLocations);
    return Ok(isSavePlayerLocSaved );
}

for ApiController you can set User property during arranging the unit test. That extension method however is looking for a ClaimsIdentity so you should provide one

The test would now look like

[TestMethod()]
public void SavePlayerLocTests() {
    //Arrange
    //Create test user
    var username = "admin";
    var userId = 2;

    var identity = new GenericIdentity(username, "");
    identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId.ToString()));
    identity.AddClaim(new Claim(ClaimTypes.Name, username));

    var principal = new GenericPrincipal(identity, roles: new string[] { });
    var user = new ClaimsPrincipal(principal);

    // Set the User on the controller directly
    var controller = new TestApiController() {
        User = user
    };

    //Act
    var actionResult = controller.SavePlayerLoc(GetLocationList());
    var response = actionResult as OkNegotiatedContentResult<IEnumerable<bool>>;

    //Assert
    Assert.IsNotNull(response);
}
like image 197
Nkosi Avatar answered Sep 22 '22 14:09

Nkosi