J'écris des cas de test à l'aide de l'API Web de test unitaire pour ASP.NET.
Maintenant, j'ai une action qui appelle une méthode que j'ai définie dans la couche service, où j'ai utilisé la ligne de code suivante.
string username = User.Identity.Name;
// do something with username
// return something
Maintenant, comment créer une méthode de test unitaire pour cela, je reçois des exceptions de référence nulles. Je suis un peu nouveau pour écrire des tests unitaires et des trucs.
Et je veux utiliser le test unitaire uniquement pour cela.
S'il vous plaît, aidez-moi sur ce point. Merci.
Celui ci-dessous n'est qu'un moyen de le faire:
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);
}
}
Voici une autre manière que j'ai trouvée dans le tutoriel de test NerdDinner
. Cela a fonctionné dans mon cas:
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));
}
Assurez-vous de lire la section complète: Mocking de la propriété User.Identity.Name
Il utilise le framework moqueur Moq
que vous pouvez installer dans votre Test project
en utilisant NuGet: http://nuget.org/packages/moq
Avec WebApi 5.0, cela est légèrement différent. Vous pouvez maintenant faire:
controller.User = new ClaimsPrincipal(
new GenericPrincipal(new GenericIdentity("user"), null));
Rien de tout cela n'a fini par fonctionner pour moi, j'ai utilisé la solution sur une autre question qui utilise Moq pour configurer un nom d'utilisateur dans ControllerContext: https://stackoverflow.com/a/6752924/347455
Lorsque je lance Unit test - dans mon cas, il utilise l'authentification Windows et Identity.Name est mon nom de domaine, que je souhaite également modifier pour le test . J'utilise donc une telle approche avec le "piratage" que je veux dans IAuthenticationFilter
Ceci est ma 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;
Si vous avez beaucoup de contrôleurs à tester, je vous conseillerais de créer une classe de base et, dans le constructeur, de créer une variable GenericIdentity
& GenericPrincipal
et de définir Thread.CurrentPrincipal
GenericPrincipal principal = new GenericPrincipal(new
GenericIdentity("UserName"),null); Thread.CurrentPrincipal = principal;
Alors Héritez cette classe. Ainsi, chaque classe de tests unitaires aura son ensemble d'objets principaux.
[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()
{
}
}
Ici, j'ai trouvé la solution pour une autre façon de définir le nom d'identité de l'utilisateur pour le test du niveau du contrôleur à partir de la méthode de test.
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;
}
}