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

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

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

有什么方法可以模拟 CreateResponse 而不使用部分模拟或直接使用“ new HttpResponseMessage (...)”?

60133 次浏览

解决这个问题的另一种方法是这样做:

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上的扩展方法将无法工作。您还必须在 Request 上设置 HttpConfiguration,否则路由和管道的其他部分将无法正常工作。

您可以像下面这样为可测试性设置控制器对象:

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;

摘自彼得 · 普罗沃斯特在 单元测试 ASP.NET Web API上的综合博客文章。

WebAPI 1在这里使用 VB 也有类似的问题。

我设法在这里混合反应,让这个工作就像这样简单:

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

只是发个帖子,以防有用。

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

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

对于 WebAPI 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 而失败。

有关更多信息,请参见 给你