Vamos a asumir que este es mi método de acción

public IHttpActionResult Get(int id)
{
    var status = GetSomething(id);
    if (status)
    {
        return Ok();
    }
    else
    {
        return NotFound();
    }
}

Prueba será

var httpActionResult = controller.Get(1);

¿Cómo puedo comprobar el código de estado http que después de esto?

InformationsquelleAutor sunil | 2013-11-12

6 Comentarios

  1. 185

    Aquí Ok() es sólo un auxiliar para el tipo de OkResult que establece el estado de la respuesta a HttpStatusCode.Ok…por lo que sólo puede verificar si la instancia de la acción resultado es un OkResult…algunos ejemplos(escrito en XUnit):

    //if your action returns: NotFound()
    IHttpActionResult actionResult = valuesController.Get(10);
    Assert.IsType<NotFoundResult>(actionResult);
    
    //if your action returns: Ok()
    actionResult = valuesController.Get(11);
    Assert.IsType<OkResult>(actionResult);
    
    //if your action was returning data in the body like: Ok<string>("data: 12")
    actionResult = valuesController.Get(12);
    OkNegotiatedContentResult<string> conNegResult = Assert.IsType<OkNegotiatedContentResult<string>>(actionResult);
    Assert.Equal("data: 12", conNegResult.Content);
    
    //if your action was returning data in the body like: Content<string>(HttpStatusCode.Accepted, "some updated data");
    actionResult = valuesController.Get(13);
    NegotiatedContentResult<string> negResult = Assert.IsType<NegotiatedContentResult<string>>(actionResult);
    Assert.Equal(HttpStatusCode.Accepted, negResult.StatusCode);
    Assert.Equal("some updated data", negResult.Content);
    • En MSTest Assert.IsInstanceOfType(httpActionResult, typeof(OkResult));
    • También, para Created<T>(url,content) su CreatedNegotiatedContentResult
    • Gracias Sunil..probablemente Created no fue un buen ejemplo para un Get operación…he cambiado el código de estado a uno diferente ahora…
    • Esto no funciona cuando se pasa un objeto a Ok()
    • El tipo de resultado será OkNegotiatedContentResult<T> cuando se pasa un objeto de tipo T a Ok()
    • Cualquier ayuda con IHttpStatusCodes que volver irregulares códigos? Como 422? return new StatusCodeResult((HttpStatusCode)422, this);
    • OkResult no funcionaba, pero OkObjectResult hizo #netcore

  2. 27

    Tiempo para resucitar a un muerto pregunta

    La actual responde a todas se basan en la fundición de la respuesta de objeto a un tipo conocido. Desafortunadamente, las respuestas no parecen tener un utilizable jerarquía o implícita de la ruta de conversión para que esto funcione sin un conocimiento íntimo del controlador de aplicación. Considere lo siguiente:

    public class MixedCodeStandardController : ApiController {
    
        public readonly object _data = new Object();
    
        public IHttpActionResult Get() {
            return Ok(_data);
        }
    
        public IHttpActionResult Get(int id) {
            return Content(HttpStatusCode.Success, _data);
        }
    }

    Pruebas de la clase:

    var testController = new MixedCodeStandardController();
    
    var getResult = testController.Get();
    var posRes = getResult as OkNegotiatedContentResult<object>;
    Assert.IsType<OkNegotiatedContentResult<object>>(getResult);
    Assert.AreEqual(HttpStatusCode.Success, posRes.StatusCode);
    Assert.AreEqual(testController._data, posRes.Content);
    
    var idResult = testController.Get(1);
    var oddRes = getResult as OkNegotiatedContentResult<object>; //oddRes is null
    Assert.IsType<OkNegotiatedContentResult<object>>(idResult); //throws failed assertion
    Assert.AreEqual(HttpStatusCode.Success, oddRes.StatusCode); //throws for null ref
    Assert.AreEqual(testController._data, oddRes.Content); //throws for null ref

    Desde fuera de la caja negra, la secuencia de respuesta es esencialmente el mismo. La prueba debe saber cómo el controlador implementado el retorno de la llamada a prueba de esta manera.

    En su lugar, utilice el HttpResponseMessage objeto de la IHttpActionResult devuelto. Esto asegura que la prueba puede ser consistente, incluso cuando el código de controlador no puede ser:

    var testController = new MixedCodeStandardController();
    
    var getResult = testController.Get();
    var getResponse = getResult.ExecuteAsync(CancellationToken.None).Result;
    Assert.IsTrue(getResponse.IsSuccessStatusCode);
    Assert.AreEqual(HttpStatusCode.Success, getResponse.StatusCode);
    
    var idResult = testController.Get(1);
    var idResponse = idResult.ExecuteAsync(CancellationToken.None).Result;
    Assert.IsTrue(idResponse.IsSuccessStatusCode);
    Assert.AreEqual(HttpStatusCode.Success, idResponse.StatusCode);
    • Una cosa que me tenía que hacer para conseguir algo como esto de trabajo (mediante la IHttpActionResult.ExecuteAsync método) fue establecer el ApiController.Atributo de la solicitud a la siguiente: new HttpRequestMessage() {Properties = { { HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration() } }}
  3. 14

    Este es el aceptado respuesta por Kiran Challa, adaptado para NUnit;

    var valuesController = controller;
    //if your action returns: NotFound()
    IHttpActionResult actionResult = valuesController.Get(10);
    var notFoundRes = actionResult as NotFoundResult;
    Assert.IsNotNull(notFoundRes);
    
    //if your action returns: Ok()
    actionResult = valuesController.Get(11);
    var posRes = actionResult as OkResult;
    Assert.IsNotNull(posRes);
    
    //if your action was returning data in the body like: Ok<string>("data: 12")
    actionResult = valuesController.Get(12);
    var conNegResult = actionResult as OkNegotiatedContentResult<string>;
    Assert.IsNotNull(conNegResult);
    Assert.AreEqual("data: 12", conNegResult.Content);
    
    //if your action was returning data in the body like: Content<string>(HttpStatusCode.Accepted, "some updated data");
    actionResult = valuesController.Get(13);
    var negResult = actionResult as NegotiatedContentResult<string>;
    Assert.IsNotNull(negResult);
    Assert.AreEqual(HttpStatusCode.Accepted, negResult.StatusCode);
    Assert.AreEqual("some updated data", negResult.Content);
  4. 2

    Si IHttpActionResult contener un objeto JSON, por ejemplo, {«token»:»A»}, podemos usar el siguiente código.

            var result = usercontroller.GetLogin("user", "password");
            Assert.IsInstanceOfType(result, typeof(OkNegotiatedContentResult<Dictionary<string,string>>));
            var content = result as OkNegotiatedContentResult<Dictionary<string, string> >;
            Assert.AreEqual("A", content.Content["token"]);
  5. 1

    Después de un par de horas de investigación y de intentar, finalmente me di cuenta de cómo poner a prueba mi Web API 2 métodos que devuelven IHttpActionResult y el uso de la OWIN y middleware de la implementación predeterminada de ASP.NET Identidad.

    Voy a probar la Get() método en el siguiente ApiController:

    public class AccountController : ApiController
    {
        private ApplicationUserManager _userManager;
        public ApplicationUserManager UserManager => _userManager ?? HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
    
        [Route("api/account"), HttpGet]
        public async Task<IHttpActionResult> Get()
        {
            var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
            if (user == null)
            {
                ModelState.AddModelError(ModelStateConstants.Errors, "Account not found! Try logging out and in again.");
                return BadRequest(ModelState);
            }
    
            var roles = await UserManager.GetRolesAsync(user.Id);
    
            var accountModel = new AccountViewModel
            {
                FullName = user.FullName,
                Email = user.Email,
                Phone = user.PhoneNumber,
                Organization = user.Organization.Name,
                Role = string.Join(", ", roles)
            };
    
            return Ok(accountModel);
        }
    
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_userManager != null)
                {
                    _userManager.Dispose();
                    _userManager = null;
                }
            }
    
            base.Dispose(disposing);
        }
    }

    Comenzar con una clase base que todas las clases de prueba se hereda de:

    public class BaseTest
    {
    protected static User CurrentUser;
    protected static IList<string> Roles;
    public BaseTest()
    {
    var email = "[email protected]";
    CurrentUser = new User
    {
    FullName = "Unit Tester",
    Email = email,
    UserName = email,
    PhoneNumber = "123456",
    Organization = new Organization
    {
    Name = "Test Organization"
    }
    };
    Roles = new List<string>
    {
    "Administrator"
    };
    }
    protected void InitializeApiController(ApiController apiController)
    {
    //Init fake controller Http and Identity data
    var config = new HttpConfiguration();
    var request = new HttpRequestMessage();
    var routeData = new HttpRouteData(new HttpRoute(""));
    apiController.ControllerContext = new HttpControllerContext(config, routeData, request)
    {
    Configuration = config
    };
    apiController.User = new GenericPrincipal(new GenericIdentity(""), new[] { "" });
    //Initialize Mocks
    var appUserMgrMock = GetMockedApplicationUserManager();
    var appSignInMgr = GetMockedApplicationSignInManager(appUserMgrMock);
    var appDbContext = GetMockedApplicationDbContext();
    //Configure HttpContext.Current.GetOwinContext to return mocks
    var owin = new OwinContext();
    owin.Set(appUserMgrMock.Object);
    owin.Set(appSignInMgr.Object);
    owin.Set(appDbContext.Object);
    HttpContext.Current = new HttpContext(new HttpRequest(null, "http://test.com", null), new HttpResponse(null));
    HttpContext.Current.Items["owin.Environment"] = owin.Environment;
    }
    private static Mock<ApplicationSignInManager> GetMockedApplicationSignInManager(Mock<ApplicationUserManager> appUserMgrMock)
    {
    var authMgr = new Mock<Microsoft.Owin.Security.IAuthenticationManager>();
    var appSignInMgr = new Mock<ApplicationSignInManager>(appUserMgrMock.Object, authMgr.Object);
    return appSignInMgr;
    }
    private Mock<ApplicationUserManager> GetMockedApplicationUserManager()
    {
    var userStore = new Mock<IUserStore<User>>();
    var appUserMgr = new Mock<ApplicationUserManager>(userStore.Object);
    appUserMgr.Setup(aum => aum.FindByIdAsync(It.IsAny<string>())).ReturnsAsync(CurrentUser);
    appUserMgr.Setup(aum => aum.GetRolesAsync(It.IsAny<string>())).ReturnsAsync(Roles);
    return appUserMgr;
    }
    private static Mock<ApplicationDbContext> GetMockedApplicationDbContext()
    {
    var dbContext = new Mock<ApplicationDbContext>();
    dbContext.Setup(dbc => dbc.Users).Returns(MockedUsersDbSet);
    return dbContext;
    }
    private static IDbSet<User> MockedUsersDbSet()
    {
    var users = new List<User>
    {
    CurrentUser,
    new User
    {
    FullName = "Testguy #1",
    Email = "[email protected]",
    UserName = "[email protected]",
    PhoneNumber = "123456",
    Organization = new Organization
    {
    Name = "Test Organization"
    }
    }
    }.AsQueryable();
    var usersMock = new Mock<DbSet<User>>();
    usersMock.As<IQueryable<User>>().Setup(m => m.Provider).Returns(users.Provider);
    usersMock.As<IQueryable<User>>().Setup(m => m.Expression).Returns(users.Expression);
    usersMock.As<IQueryable<User>>().Setup(m => m.ElementType).Returns(users.ElementType);
    usersMock.As<IQueryable<User>>().Setup(m => m.GetEnumerator()).Returns(users.GetEnumerator);
    return usersMock.Object;
    }
    }

    La InitializeApiController método contiene la carne y las patatas.

    Ahora podemos escribir nuestras pruebas para AccountController:

    public class AccountControllerTests : BaseTest
    {
    private readonly AccountController _accountController;
    public AccountControllerTests()
    {
    _accountController = new AccountController();
    InitializeApiController(_accountController);
    }
    [Test]
    public async Task GetShouldReturnOk()
    {
    var result = await _accountController.Get();
    var response = await result.ExecuteAsync(CancellationToken.None);
    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    }
    }

    Para que todo funcione, tendrás que instalar un montón de Microsoft.OWIN.* y Microsoft.AspNet.* paquetes, voy a pegar mi packages.config aquí:

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
    <package id="Castle.Core" version="4.3.1" targetFramework="net472" />
    <package id="EntityFramework" version="6.2.0" targetFramework="net472" />
    <package id="Microsoft.AspNet.Identity.Core" version="2.2.2" targetFramework="net472" />
    <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.2.2" targetFramework="net472" />
    <package id="Microsoft.AspNet.Identity.Owin" version="2.2.2" targetFramework="net472" />
    <package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net472" />
    <package id="Microsoft.AspNet.WebApi.Core" version="5.2.7" targetFramework="net472" />
    <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.7" targetFramework="net472" />
    <package id="Microsoft.Owin" version="4.0.1" targetFramework="net472" />
    <package id="Microsoft.Owin.Host.SystemWeb" version="4.0.1" targetFramework="net472" />
    <package id="Microsoft.Owin.Security" version="4.0.1" targetFramework="net472" />
    <package id="Microsoft.Owin.Security.Cookies" version="4.0.1" targetFramework="net472" />
    <package id="Microsoft.Owin.Security.OAuth" version="4.0.1" targetFramework="net472" />
    <package id="Moq" version="4.10.1" targetFramework="net472" />
    <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net472" />
    <package id="NUnit" version="3.11.0" targetFramework="net472" />
    <package id="Owin" version="1.0" targetFramework="net472" />
    <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />
    <package id="System.Threading.Tasks.Extensions" version="4.5.2" targetFramework="net472" />
    </packages>

    La prueba es muy simple, pero demuestra que todo funciona 🙂

    Feliz pruebas!

Dejar respuesta

Please enter your comment!
Please enter your name here