web-dev-qa-db-fra.com

Test unitaire d'écriture pour les méthodes utilisant User.Identity.Name dans l'API Web ASP.NET

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.

39
Yasser

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);
    }
}
45
tugberk

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

16

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));
13
jonnii

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

1
pennstatephil

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

0
Alexander

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;
0
Nikita

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()
   {
   }
}
0
user3507981

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;
            }
        }
0
Umapathy