【问题标题】:ASP.NET WebApi unit testing with Request.CreateResponse使用 Request.CreateResponse 进行 ASP.NET WebApi 单元测试
【发布时间】:2012-06-07 18:44:00
【问题描述】:

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

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

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

【问题讨论】:

  • 为什么要模拟CreateResponse?为什么不对返回的 HttpResponseMessage ContentStatusCode 属性断言设置了正确的值?
  • 如果我以单元测试的形式运行此方法,它将失败,但未设置配置。
  • 好吧,真丢人,我只需要写 this.Request.CreateResponse(HttpStatusCode.Accepted, createdProduct, GlobalConfiguration.Configuration)

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


【解决方案1】:

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

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,否则路由和管道的其他部分将无法正常运行。

【讨论】:

  • 是的,这可能也有效,但似乎 Request.CreateResponse 也有效。
  • 添加 GlobalConfiguration.Configuration 仍然使请求为空。设置请求对我有用,但这并不是我的问题的结束,因为我的 Action 也在调用 Url.Link 并且没有定义路由名称。
  • 设置 ControllerContext after 这个调用也给了我这个错误,但仅限于 WebApi 5.0.0。但是如果我在请求 last 上设置 HttpConfiguration 对象,它就可以正常工作。
  • 这很好用,但我不明白为什么会这样。你能在答案中详细说明吗?
【解决方案2】:

您可以像这样设置控制器对象以实现可测试性:

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 上的综合博文。

【讨论】:

【解决方案3】:

对于 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 了解更多信息。

【讨论】:

    【解决方案4】:

    WebAPI 1 在此处使用 VB 时遇到类似问题。

    我设法在此处混合响应以使其像这样简单地工作:

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

    只是发布以防万一。

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-09
        • 1970-01-01
        • 1970-01-01
        • 2015-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多