4

I'm currently working with Web API v5.2.2 and I'm writing Unit Test code for one of the controllers. The problem I encountered was happening in ApiController.User part.

I have a custom Identity for the user implemented IIdentity Interface:

public class CustomIdentity : IIdentity { //Constructor and methods } 

The CustomIdentity was set in the HttpRequest in normal usage. But since I'm only testing the query functionalities in the Unit Test, I just called the controller and its methods instead of sending requests.

Thus, I have to insert the User Identity into the Thread, and I tried with following ways:

var controller = new AccountsController(new AccountUserContext()); 

First try:

controller.User = new ClaimsPrincipal(new GenericPrincipal(new CustomIdentity(user), roles.Distinct().ToArray())); 

And second try:

IPrincipal principal = null; principal = new GenericPrincipal(new CustomIdentity(user), roles.Distinct().ToArray()); Thread.CurrentPrincipal = principal; if (HttpContext.Current != null) { HttpContext.Current.User = principal; } 

However, I got this error from both attempts:

Object reference not set to an instance of an object.

And I found the User identity remains null in the thread.

Anyone tried this method before? Thank you for the advice!

4
  • 1
    Your first try is working for me. Where exactly is the exception being thrown? You could try controller.User = new ClaimsPrincipal(new CustomIdentity(user)); Commented Mar 15, 2016 at 16:43
  • Can you show a snippet of one of the actions that throws the error? Where exactly is the exception being thrown? Commented Mar 15, 2016 at 17:08
  • Your first test also works for me. But as we don't know what going on within the controller's action there is no way to be sure what is throwing the exception Commented Mar 15, 2016 at 17:26
  • Controller's action only contains Linq query, and the exception was thrown after controller.User = new ClaimsPrincipal(...). I also didn't have a clue what went wrong inside the Metadata file. Commented Mar 15, 2016 at 17:38

1 Answer 1

2

You said

The CustomIdentity was set in the HttpRequest in normal usage.

Are you attaching a request to the controller when assembling your test.

Check the examples here

Unit Testing Controllers in ASP.NET Web API 2

[TestMethod] public void QueryAccountControllerTest() { // Arrange var user = "[Username Here]" var controller = new AccountsController(new AccountUserContext()); //Set a fake request. If your controller creates responses you will need tis controller.Request = new HttpRequestMessage { RequestUri = new Uri("http://localhost/api/accounts") }; controller.Configuration = new HttpConfiguration(); controller.User = new ClaimsPrincipal(new CustomIdentity(user)); // Act ... call action // Assert ... assert result } 
Sign up to request clarification or add additional context in comments.

1 Comment

I did attach the Request to the controller altogether with Configuration. But I tried the suggestion @ChrisS commented which is controller.User = new ClaimsPrincipal(new CustomIdentity(user)); and it's working fine now. Furthermore, it was hard to attach the exception throwing place since it all happened in the metadata inside controller.User = new ClaimsPrincipal(..); Thank you for the help.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.