Kiểm tra đơn vị ASP.NET WebApi với Request.CreateResponse


147

Tôi đang cố gắng viết một số bài kiểm tra đơn vị cho ApiControll của tôi và gặp một số vấn đề. Có một phương thức mở rộng thú vị được gọi là Request.CreateResponse giúp ích rất nhiều cho việc tạo phản hồi.

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

Có cách nào để giả lập CreatResponse mà không cần sử dụng giả một phần hoặc sử dụng trực tiếp "httpResponseMessage mới (...)" không?


1
Tại sao bạn muốn chế giễu CreateResponse? Tại sao không khẳng định trên các thuộc tính được trả về HttpResponseMessage ContentStatusCodecác giá trị chính xác được đặt?
nemev

3
Nếu tôi chạy thử nghiệm đơn vị mẫu phương thức này, nó sẽ thất bại với ngoại lệ là cấu hình không được đặt.
asa

1
Ok, xấu hổ về tôi, tôi chỉ cần thiết để ghi this.Request.CreateResponse (HttpStatusCode.Accepted, createdProduct, GlobalConfiguration.Configuration)
asa

Câu trả lời:


243

Một cách khác để giải quyết điều này là làm như sau:

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

Nếu bạn đang nâng cấp lên webapi 5.0, thì bạn cần thay đổi điều này thành:

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

Lý do tại sao bạn cần phải làm điều này là vì bạn phải Requestđiền vào bộ điều khiển nếu không các phương thức mở rộng trên Requestsẽ không hoạt động. Bạn cũng phải có một HttpConfigurationbộ trên Yêu cầu định tuyến và các phần khác của đường ống sẽ không hoạt động chính xác.


Vâng, điều đó cũng có thể hoạt động, nhưng có vẻ như Request.CreateResponse cũng hoạt động.
asa

4
Thêm GlobalConfiguration.Configuration vẫn để lại yêu cầu null. Đặt Yêu cầu có hiệu quả với tôi, tuy nhiên đây không phải là vấn đề của tôi vì Hành động của tôi cũng đang gọi Url.Link và tên tuyến đường không được xác định.
đánh lừa

Trợ giúp để thiết lập lộ trình stackoverflow.com/questions/11779311/ từ
đánh lừa

Việc đặt Bộ điều khiển Nội dung sau cuộc gọi này cũng mang lại cho tôi lỗi đó, nhưng chỉ với WebApi 5.0.0. Nhưng nếu tôi đặt đối tượng HTTPConfiguration trên Yêu cầu cuối cùng , nó sẽ hoạt động tốt.
mikebridge

Điều này hoạt động hoàn hảo, nhưng tôi không hiểu tại sao điều này hoạt động. Bạn có thể giải thích điều này trong câu trả lời?
Jan_V

24

Bạn có thể thiết lập đối tượng điều khiển để kiểm tra như thế này:

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;

Sao chép từ bài đăng blog toàn diện của Peter Provost về API kiểm tra đơn vị API Web .


1
Bạn cũng có thể quan tâm đến các tài liệu MS liên quan đến vấn đề này: docs.microsoft.com/en-us/aspnet/web-api/overview/ trộm Bạn cũng có thể cần thêm tài liệu tham khảo vào System.Web.Http và System.Net. Http
Aaron Hoffman

4

Đối với API Web 2, bạn chỉ cần thêm

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

Thích như vậy

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

Điều quan trọng là đặt Yêu cầu và Cấu hình trên bộ điều khiển. Nếu không, thử nghiệm sẽ thất bại với ArgumentNullException hoặc UnlimitedOperationException.

Xem ở đây để biết thêm.


1

WebAPI 1 ở đây với một vấn đề tương tự bằng cách sử dụng VB.

Tôi đã quản lý để trả lời lai ở đây để làm cho nó hoạt động đơn giản như thế này:

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

Chỉ cần đăng trong trường hợp nó giúp bất cứ ai.


0

Trong lớp thử nghiệm của bạn, tạo một thể hiện của lớp trình điều khiển. ví dụvar customerController= new CustomerController();

customerController.Request = new HttpRequestMessage();
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.