Request.CreateResponse를 사용한 ASP.NET WebApi 장치 테스트


147

내 ApiController에 대한 단위 테스트를 작성하려고하는데 몇 가지 문제가 있습니다. Request.CreateResponse라는 멋진 확장 메서드가 응답 생성에 많은 도움이됩니다.

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

부분 모의를 사용하지 않거나 "new HttpResponseMessage (...)"를 직접 사용하지 않고 CreateResponse를 조롱하는 방법이 있습니까?


1
왜 조롱하고 CreateResponse싶습니까? 올바른 값이 설정 되어있는 반환 된 속성 HttpResponseMessage ContentStatusCode속성을 주장하지 않는 이유는 무엇 입니까?
nemesv 2016 년

3
단위 테스트에서이 방법을 실행하면 구성이 설정되지 않은 경우를 제외하고 실패합니다.
asa

1
좋아, 부끄러운 일, 나는 이것을 작성해야했다 .Request.CreateResponse (HttpStatusCode.Accepted, createdProduct, GlobalConfiguration.Configuration)
asa

답변:


243

이를 해결하는 또 다른 방법은 다음을 수행하는 것입니다.

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도 작동하는 것 같습니다.
asa

4
GlobalConfiguration.Configuration을 추가하면 여전히 요청이 null입니다. 요청을 설정하면 나에게 도움이되었지만 내 동작이 Url.Link를 호출하고 경로 이름이 정의되지 않았기 때문에 문제가 끝나지 않았습니다.
바보 :

route 설정을 도와주세요 stackoverflow.com/questions/11779311/…
foolshat

이 호출 ControllerContext를 설정하면 해당 오류가 발생하지만 WebApi 5.0.0에서만 발생합니다. 그러나 Request last 에 HttpConfiguration 객체를 설정하면 정상적으로 작동합니다.
mikebridge

이것은 완벽하게 작동하지만 이것이 왜 작동하는지 이해하지 못합니다. 답을 자세히 설명해 주시겠습니까?
Jan_V

24

다음과 같이 테스트 가능하도록 제어기 오브젝트를 설정할 수 있습니다.

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 에 대한 포괄적 인 블로그 게시물에서 복사했습니다 .


1
docs.microsoft.com/en-us/aspnet/web-api/overview/… 와 관련된 MS 문서에 관심이있을 수도 있습니다 . System.Web.Http 및 System.Net에 대한 참조를 추가해야 할 수도 있습니다. Http
Aaron Hoffman

4

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으로 테스트가 실패합니다.

자세한 내용은 여기 를 참조 하십시오 .


1

VB를 사용하는 비슷한 문제가있는 WebAPI 1.

나는 이것이 다음과 같이 간단하게 작동하도록 하이브리드 응답을 관리했습니다.

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

누군가에게 도움이 될 수 있도록 게시하십시오.


0

테스트 클래스에서 컨트롤러 클래스의 인스턴스를 작성하십시오. 예 :var customerController= new CustomerController();

customerController.Request = new HttpRequestMessage();
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.