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 (...)"?

como un
fuente
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.

jonnii
fuente
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 .

mono68
fuente
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.

Dan Friedman
fuente
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.

Rudy Scoggins
fuente
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());
Kiran Chaudhari
fuente