Saltar al contenido

xunit – cómo obtener HttpContext.User.Identity en pruebas unitarias

Solución:

Realmente no hay necesidad de burlarse del HttpContext en este caso particular.

Utilizar el DefaultHttpContext y establecer los miembros necesarios para realizar la prueba hasta su finalización

Por ejemplo

[Theory]
[MemberData(nameof(TestCreateUsergroupItemData))]
public async Task TestPostUsergroupItem(Usergroup usergroup) {
    // Arrange

    //...

    var identity = new GenericIdentity("some name", "test");
    var contextUser = new ClaimsPrincipal(identity); //add claims as needed

    //...then set user and other required properties on the httpContext as needed
    var httpContext = new DefaultHttpContext() {
        User = contextUser;
    };

    //Controller needs a controller context to access HttpContext
    var controllerContext = new ControllerContext() {
        HttpContext = httpContext,
    };
    //assign context to controller
    UsergroupController controller = new UsergroupController(context, mapper) {
        ControllerContext = controllerContext,
    };

    // Act
    var controllerResult = await controller.Post(usergroup).ConfigureAwait(false);

    // Assert
    ....
}

En primer lugar, le sugiero que utilice IHttpContextAccessor acceder HttpContext e inyectar a través de Dependency Injection En lugar de usar HttpContext directamente. Puede seguir esta documentación de Microsoft para comprender el uso y la inyección de IHttpContextAccessor.

Con el código anterior, su código se verá de la siguiente manera para inyectar IHttpContextAccessor

private IHttpContextAccessor  httpContextAccessor;
public class UsergroupController(IHttpContextAccessor httpContextAccessor, ...additional parameters)
{
   this.httpContextAccessor = httpContextAccessor;
   //...additional assignments
}

Una vez IHttpContextAccessor se inyecta, puede acceder a la identidad como this.httpContextAccessor.HttpContext.User.Identity

Entonces el GetUserId debería cambiar como

protected string GetUserId()
{
    if (this.httpContextAccessor.HttpContext.User.Identity is ClaimsIdentity identity)
    {
        IEnumerable<Claim> claims = identity.Claims;
        return claims.ToList()[0].Value;
    }

    return "";
}

Con el cambio anterior, ahora puede inyectar fácilmente el simulacro de IHttpContextAccessor para pruebas unitarias. Puede usar el siguiente código para crear el simulacro:

private static ClaimsPrincipal user = new ClaimsPrincipal(
                        new ClaimsIdentity(
                            new Claim[] { new Claim("MyClaim", "MyClaimValue") },
                            "Basic")
                        );


private static Mock<IHttpContextAccessor> GetHttpContextAccessor()
{
        var httpContextAccessorMock = new Mock<IHttpContextAccessor>();
        httpContextAccessorMock.Setup(h => h.HttpContext.User).Returns(user);
        return httpContextAccessorMock;
}

Con la configuración anterior, en su método de prueba, puede inyectar el simulacro de IHttpContextAccessor mientras instancia el objeto de UsergroupController.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *