使用Request.CreateResponse进行ASP.NET WebApi单元测试

时间:2012-06-03 07:39:13

标签: c# unit-testing asp.net-web-api mocking httpresponse

我正在尝试为我的ApiController编写一些单元测试并遇到一些问题。有一个很好的扩展方法叫做Request.CreateResponse,可以帮助生成响应。

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

有没有办法在不使用部分模拟或直接使用“new HttpResponseMessage(...)”的情况下模拟CreateResponse?

5 个答案:

答案 0 :(得分:233)

解决此问题的另一种方法是执行以下操作:

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

如果要升级到webapi 5.0,则需要将其更改为:

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

您需要执行此操作的原因是您必须在控制器上填充Request,否则Request上的扩展方法将无效。您还必须在请求中设置HttpConfiguration,否则路由和管道的其他部分将无法正常运行。

答案 1 :(得分:23)

您可以设置控制器对象的可测试性,如下所示:

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;

复制自Peter Provost关于Unit Testing ASP.NET Web API的综合博客文章。

答案 2 :(得分:1)

对于Web API 2,您只需添加

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

喜欢

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

在控制器上设置“请求和配置”很重要。否则,测试将失败,并显示ArgumentNullException或InvalidOperationException。

有关更多信息,请参见here

答案 3 :(得分:0)

WebAPI 1此处使用VB的类似问题。

我设法在这里进行混合响应以使其工作如此简单:

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

只是发布以防万一。

答案 4 :(得分:0)

在测试类中,创建控制器类的实例。     例如var customerController= new CustomerController();

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