Prueba de unidad ASP.NET WebApi con Request.CreateResponse


147

Estoy tratando de escribir algunas pruebas unitarias para mi ApiController y enfrenté algunos problemas. Hay un buen método de extensión llamado Request.CreateResponse que ayuda mucho a generar respuestas.

public HttpResponseMessage Post(Product product)
{
  var createdProduct = repo.Add(product);
  return this.Request.CreateResponse(HttpStatusCode.Created, createdProduct);
}

¿Hay alguna forma de burlarse de CreateResponse sin usar simulacros parciales o el uso directo de "new HttpResponseMessage (...)"?


1
¿Por qué quieres burlarte de la CreateResponse? ¿Por qué no afirmar en las propiedades devueltas HttpResponseMessage Contenty StatusCodeque los valores correctos están establecidos?
nemesv

3
Si ejecuto este método de pruebas unitarias, fallará con la excepción de que la configuración no está establecida.
asa

1
Ok, la culpa es mía, yo sólo necesitaba this.Request.CreateResponse escritura (HttpStatusCode.Accepted, createdProduct, GlobalConfiguration.Configuration)
ASA

Respuestas:


243

Otra forma de resolver esto es hacer lo siguiente:

controller.Request = new HttpRequestMessage();
controller.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, 
                                  new HttpConfiguration());

Si está actualizando a webapi 5.0, deberá cambiar esto a:

controller.Request = new HttpRequestMessage();
controller.Request.SetConfiguration(new HttpConfiguration());

La razón por la que necesita hacer esto es porque debe haber Requestrellenado el controlador; de lo contrario, los métodos de extensión Requestno funcionarán. También debe tener un HttpConfigurationconjunto en la solicitud; de lo contrario, el enrutamiento y otras partes de la tubería no funcionarán correctamente.


Sí, eso podría funcionar también, pero parece que Request.CreateResponse también funciona.
asa

44
Al agregar GlobalConfiguration, la configuración dejó la solicitud nula. Configurar la solicitud funcionó para mí, sin embargo, este no fue el final de mis problemas, ya que mi Acción también estaba llamando a Url.Link y el nombre de la ruta no estaba definido.
tonto

Ayuda para configurar la ruta stackoverflow.com/questions/11779311/…
foolshat

Configurar el ControllerContext después de esta llamada también me da ese error, pero solo con WebApi 5.0.0. Pero si configuro el objeto HttpConfiguration en la última solicitud , funciona bien.
mikebridge

Esto funciona perfectamente, pero no entiendo por qué funciona. ¿Podría elaborar esto en la respuesta?
Jan_V

24

Puede configurar el objeto del controlador para la capacidad de prueba de esta manera:

var config = new HttpConfiguration();
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/products");
var route = config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}");
var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "products" } });

controller.ControllerContext = new HttpControllerContext(config, routeData, request);
controller.Request = request;
controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;

Copiado de la publicación de blog integral de Peter Provost sobre Unit Testing ASP.NET Web API .


1
También puede estar interesado en los documentos de MS relacionados con esto: docs.microsoft.com/en-us/aspnet/web-api/overview/… Es posible que también necesite agregar referencias a System.Web.Http y System.Net. Http
Aaron Hoffman

4

Para Web API 2, simplemente puede agregar

controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();

Al igual que

[TestMethod]
public void GetReturnsProduct()
{
    // Arrange
    var controller = new ProductsController(repository);
    controller.Request = new HttpRequestMessage();
    controller.Configuration = new HttpConfiguration();

    // Act
    var response = controller.Get(10);

    // Assert
    Product product;
    Assert.IsTrue(response.TryGetContentValue<Product>(out product));
    Assert.AreEqual(10, product.Id);
}

Es importante establecer Solicitud y Configuración en el controlador. De lo contrario, la prueba fallará con una excepción ArgumentNullException o InvalidOperationException.

Ver aquí para más información.


1

WebAPI 1 aquí con un problema similar al usar VB.

Logré respuestas híbridas aquí para que esto funcione tan simple como esto:

Dim request As HttpRequestMessage = New HttpRequestMessage()
Return request.CreateResponse(HttpStatusCode.BadRequest, myCustomClassObject, GlobalConfiguration.Configuration)

Solo publicar en caso de que ayude a alguien.


0

En su clase de prueba, cree una instancia de la clase de controlador. p.ejvar customerController= new CustomerController();

customerController.Request = new HttpRequestMessage();
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.