Prueba Unitaria de Escritura para métodos que utilizan User.Identity.Name en ASP.NET API WEB


Estoy escribiendo casos de prueba usando la Prueba Unitaria para ASP.NET Web API.

Ahora tengo una acción que hace una llamada a algún método que he definido en la capa de servicio, donde he utilizado la siguiente línea de código.

string username = User.Identity.Name;
// do something with username
// return something

Ahora cómo crear el método de prueba unitaria para esto, estoy obteniendo excepciones de referencia null. Soy un poco nuevo en la escritura de pruebas unitarias y esas cosas.

Y quiero usar la Prueba Unitaria solo para esto.

Por favor ayúdame con esto. Gracias.

Author: Konrad Borowski, 2012-10-08

8 answers

La siguiente es solo una forma de hacer esto:

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);
    }
}
 42
Author: tugberk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-21 09:15:48

Aquí hay otra forma que encontré en el tutorial de prueba NerdDinner. Funcionó en mi caso:

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

Asegúrese de leer la sección completa: Burlándose de la User.Identity.Name propiedad

Utiliza el framework de burla Moq que puedes instalar en tu Test project usando NuGet: http://nuget.org/packages/moq

 15
Author: Leniel Maccaferri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-03 18:00:47

Con WebAPI 5.0 esto es ligeramente diferente. Ahora puedes hacer:

controller.User = new ClaimsPrincipal(
  new GenericPrincipal(new GenericIdentity("user"), null));
 13
Author: jonnii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-17 18:43:39

Nada de esto terminó funcionando para mí, usé la solución en otra pregunta que usa Moq para configurar un nombre de usuario en el ControllerContext: https://stackoverflow.com/a/6752924/347455

 1
Author: pennstatephil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:47

Aquí encontré la solución para otra manera que cómo establecer el nombre de identidad de usuario para la prueba de nivel del controlador desde el método de prueba.

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
Author: Umapathy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-01 12:28:58

Cuando corro Unit test-en mi caso utiliza autenticación de Windows y Identity.Name es mi nombre de dominio, que también quiero cambiar para la prueba. Así que utilizo tal enfoque con 'hacking' cosas que quiero en IAuthenticationFilter

 0
Author: Alexander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-11 08:45:34

Si tiene muchos Controladores para Probar, entonces sugeriría crear una clase base y en el constructor crear una GenericIdentity & GenericPrincipal y set Thread.CurrentPrincipal

GenericPrincipal principal = new GenericPrincipal(new 
    GenericIdentity("UserName"),null); Thread.CurrentPrincipal = principal; 

Entonces Hereda esa clase .. De esta manera, cada clase de Prueba Unitaria tendrá el Objeto Principle 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()
   {
   }
}
 0
Author: user3507981,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-12 02:08:08

Esta es mi solución.

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
Author: Nikita,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-08 08:57:26