问题
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.
And I want to use Unit Test only for this.
Please help me out on this. Thanks.
回答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);
}
}
回答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
回答3:
With WebApi 5.0 this is slightly different. You can now do:
controller.User = new ClaimsPrincipal(
new GenericPrincipal(new GenericIdentity("user"), null));
回答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
回答5:
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;
}
}
回答6:
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
回答7:
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()
{
}
}
回答8:
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;
来源:https://stackoverflow.com/questions/12780185/writing-unit-test-for-methods-that-use-user-identity-name-in-asp-net-web-api