2013-03-14 3 views
5

.NET Web Api에 대한 경험이 많지 않지만 Pluralsight에 대한 John Papa의 SPA 응용 프로그램 자습서를 따라 오면서 잠깐 작업 해 왔습니다. 응용 프로그램은 정상적으로 작동하지만, 지금 당장 고민하고있는 것은 단위 테스트 POST 컨트롤러입니다.단위 테스트 후 컨트롤러 .NET Web Api

단위 테스트 웹 API 컨트롤러에 대한이 놀라운 가이드를 따라 왔습니다. 나를위한 유일한 문제는 POST 메서드를 테스트 할 때입니다.

내 컨트롤러는 다음과 같습니다

[ActionName("course")] 
    public HttpResponseMessage Post(Course course) 
    { 
     if (course == null) 
      throw new HttpResponseException(HttpStatusCode.NotAcceptable); 
     try 
     { 
      Uow.Courses.Add(course); 
      Uow.commit(); 
     } 
     catch (Exception) 
     { 
      throw new HttpResponseException(HttpStatusCode.InternalServerError); 
     } 

     var response = Request.CreateResponse(HttpStatusCode.Created, course); 

     string uri = Url.Link(routeName: "ControllerActionAndId", 
     routeValues: new { id = course.Id }); 

     response.Headers.Location = new Uri(uri); 

     return response; 
    } 

그리고 내 단위 테스트는 다음과 같습니다

public static void SetupPostControllerForTest(ApiController controller) 
    { 

     var config = new HttpConfiguration(); 
     var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/courses/course"); 
     var route = config.Routes.MapHttpRoute(
      name: "ControllerActionAndId", 
      routeTemplate: "api/{controller}/{action}/{id}", 
      defaults: null, 
      constraints: new { id = @"^\d+$" } 
     ); 

     var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "courses" }, { "action", "course" } }); 

     controller.ControllerContext = new HttpControllerContext(config, routeData, request); 
     controller.Request = request; 
     controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; 
    } 

내가 단위 테스트를 디버깅 : 도움말 기능으로

[Test] 
    public void PostShouldReturnHttpResponse() 
    { 
     var populatedPostController = new CoursesController(new TestUOW()); 

     SetupPostControllerForTest(populatedPostController); 

     var course = new Course 
     { 
      Id = 12, 
      Author = new UserProfile() 
      { 
       Firstname = "John", 
       Lastname = "Johnson", 
      }, 
      Description = "Testcourse", 
      Title = "Test Title" 
     }; 

      var responses = populatedPostController.Post(course); 

      ObjectContent content = responses.Content as ObjectContent; 
      Course result = (Course)content.Value; 
      Assert.AreSame(result, course); 
    } 

그것은 다음과 같이 실패합니다 :

 string uri = Url.Link(routeName: "ControllerActionAndId", 
     routeValues: new { id = course.Id }); 

     response.Headers.Location = new Uri(uri); //Exception because uri = null 

Url.Link에서 경로를 찾을 수없는 것 같습니다.

나는 또한 this 가이드를 시도했지만 위의 예제가 실제로 필요합니다.

내가 여기에 정말 기본적인 것을 놓치고 있습니까?

+1

'SetupPostControllerForTest' 메쏘드의 끝에 다음 줄을 추가하려고 시도하십시오. controller.Request.Properties [HttpPropertyKeys.HttpRouteDataKey] = routeData; – nemesv

+0

네, 이제 작동합니다! 그것은 피곤할 때 일어나는 일입니다. 고마워요! –

답변

4

네메스 브가 언급 한대로 구성에 한 줄 누락되었습니다.

controller.Request.Properties[HttpPropertyKeys.HttpRouteDataKey] = routeData 

위에서 알 수 있듯이 UrlHelper를 사용하기위한 컨트롤러 구성은 매우 복잡합니다. 그 이유로 컨트롤러 클래스에서 UrlHelper를 사용하지 않는 경향이 있습니다. 필자는 일반적으로 IUrlHelper와 같은 테스트를 더 쉽게 수행 할 수 있도록 외부 종속성을 도입하여 단위 테스트에서 동작을 조롱합니다.

public interface IUrlHelper 
    { 
     string Link(string routeName, object routeValues); 
     string Route(string routeName, object routeValues); 
    } 

    public class UrlHelperWrapper : IUrlHelper 
    { 
     UrlHelper helper; 

     public UrlHelperWrapper(UrlHelper helper) 
     { 
      this.helper = helper; 
     } 

     public string Link(string routeName, object routeValues) 
     { 
      return this.helper.Link(routeName, routeValues); 
     } 

     public string Route(string routeName, object routeValues) 
     { 
      return this.helper.Route(routeName, routeValues); 
     } 
    } 

나는 실제 웹 API에서이 UrlHelperWraper 및 테스트에 IUrlHelper 인터페이스의 모의를 주입. 이렇게하면 경로와 함께 복잡한 구성을 모두 수행 할 필요가 없습니다.

감사합니다. 파블로.

+0

와우. 어떻게 그럴 수 : /. UrlHelper를 처리하는 더 깨끗한 방법처럼 보입니다. 좋은 분, 고마워! –

+0

안녕하세요 @ 파블로 Cibraro 당신이 몇 가지 라이브 예제를 줄 수있을 것이라고, 나는 웹 API에 대한 처음으로 단위 테스트를 작성하고 내가 여기에 착륙 가장 최적화 된 방법으로 그들을 만들 수 있습니다. URL 도우미를 활용하는 방법과 URl 도우미를 사용하여 제거한 질문에있는 내용을 이해할 수 없습니다. 어떤 도움이라도 대단히 감사하겠습니다. –