web-dev-qa-db-fra.com

Comment ajouter des revendications dans une simulation de revendications

J'essaie de tester mon code de contrôleur unitaire qui obtient les informations du ClaimsPrincipal.Current. Dans le code du contrôleur I

public class HomeController {
    public ActionResult GetName() {
        return Content(ClaimsPrincipal.Current.FindFirst("name").Value);
    }
}

Et j'essaie de moquer mon ClaimsPrincipal avec des revendications, mais je n'ai toujours aucune valeur fictive de la revendication.

// Arrange
IList<Claim> claimCollection = new List<Claim>
{
    new Claim("name", "John Doe")
};

var identityMock = new Mock<ClaimsIdentity>();
identityMock.Setup(x => x.Claims).Returns(claimCollection);

var cp = new Mock<ClaimsPrincipal>();
cp.Setup(m => m.HasClaim(It.IsAny<string>(), It.IsAny<string>())).Returns(true);
cp.Setup(m => m.Identity).Returns(identityMock.Object);

var sut = new HomeController();

var contextMock = new Mock<HttpContextBase>();
contextMock.Setup(ctx => ctx.User).Returns(cp.Object);

var controllerContextMock = new Mock<ControllerContext>();
controllerContextMock.Setup(con => con.HttpContext).Returns(contextMock.Object);
controllerContextMock.Setup(con => con.HttpContext.User).Returns(cp.Object);

sut.ControllerContext = controllerContextMock.Object;

// Act
var viewresult = sut.GetName() as ContentResult;

// Assert
Assert.That(viewresult.Content, Is.EqualTo("John Doe"));

Le viewresult.Content est vide lorsque j'exécute le test unitaire. Toute aide si je peux ajouter la revendication fictive. Merci.

23
Henry

Tout d'abord, il vous manque cette ligne dans votre test:

Thread.CurrentPrincipal = cp.Object;  

(puis le nettoyer dans TearDown).

Deuxièmement, comme @trailmax l'a mentionné, se moquer des principaux objets n'est pas pratique. Dans ton cas, ClaimsPrincipal.FindFirst (selon la source décompilée) examine les champs privés de son instance, c'est la raison pour laquelle le mocking n'a pas aidé.

Je préfère utiliser deux classes simples qui me permettent de tester les fonctionnalités basées sur les revendications:

    public class TestPrincipal : ClaimsPrincipal
    {
        public TestPrincipal(params Claim[] claims) : base(new TestIdentity(claims))
        {
        }
    }

    public class TestIdentity : ClaimsIdentity
    {
        public TestIdentity(params Claim[] claims) : base(claims)
        {
        }
    }

puis votre test se réduit à:

    [Test]
    public void TestGetName()
    {
        // Arrange
        var sut = new HomeController();
        Thread.CurrentPrincipal = new TestPrincipal(new Claim("name", "John Doe"));

        // Act
        var viewresult = sut.GetName() as ContentResult;

        // Assert
        Assert.That(viewresult.Content, Is.EqualTo("John Doe"));
    }

et ça passe maintenant, je viens de vérifier.

28
felix-b

Vous n'avez pas besoin de vous moquer ClaimsPrincipal il n'a pas de dépendances extérieures et vous pouvez le créer sans se moquer:

var claims = new List<Claim>() 
{ 
    new Claim(ClaimTypes.Name, "username"),
    new Claim(ClaimTypes.NameIdentifier, "userId"),
    new Claim("name", "John Doe"),
};
var identity = new ClaimsIdentity(claims, "TestAuthType");
var claimsPrincipal = new ClaimsPrincipal(identity);

Et je ne suis pas sûr de ce que vous testez ici. Certes, "John Doe" ne fera pas partie de viewResult.Content car il n'a jamais été défini pour cela.

54
trailmax