web-dev-qa-db-fra.com

Test d'unité ASP.NET WebApi avec Request.CreateResponse

J'essaie d'écrire des tests unitaires pour mon ApiController et j'ai rencontré quelques problèmes. Il existe une méthode d'extension Nice appelée Request.CreateResponse qui aide beaucoup à générer une réponse. 

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

Existe-t-il un moyen de simuler CreateResponse sans utiliser de simulacres partiels ou d'utiliser directement "nouveau HttpResponseMessage (...)"?

140
asa

Une autre solution consiste à effectuer les opérations suivantes:

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

Si vous effectuez une mise à niveau vers webapi 5.0, vous devrez le remplacer par:

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

Ceci est dû au fait que vous devez avoir Request rempli sur le contrôleur, sinon les méthodes d'extension sur Request ne fonctionneront pas. Vous devez également définir une variable HttpConfiguration sur la demande, sinon le routage et les autres parties du pipeline ne fonctionneront pas correctement.

231
jonnii

Vous pouvez configurer l'objet contrôleur pour la testabilité comme ceci:

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;

Copié du billet de blog complet de Peter Provost sur Test d'unité API Web ASP.NET .

23
mono68

WebAPI 1 ici avec un problème similaire en utilisant VB.

J'ai réussi à hybrider les réponses ici pour que cela fonctionne aussi simplement que ceci:

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

Il suffit de poster au cas où cela aiderait quelqu'un.

0
Rudy Scoggins

Pour Web API 2, vous pouvez simplement ajouter

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

Ainsi

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

Il est important de définir Request et Configuration sur le contrôleur. Sinon, le test échouera avec une exception ArgumentNullException ou InvalidOperationException.

Voir ici pour plus d'informations.

0
Dan Friedman

Dans votre classe de test, créez une instance de la classe de contrôleur . par exemple var customerController= new CustomerController();

customerController.Request = new HttpRequestMessage();
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
0
Kiran Chaudhari