2013-03-14 8 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; 
    } 

iはユニットテストをデバッグ:ヘルプ機能付き

[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

はい、Nemesvが述べたように、設定に1行が欠けています。

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

私は、実際のWeb APIでこのUrlHelperWraperを注入し、テストでIUrlHelperインターフェイスのモック。これを行うことで、その複雑な設定をすべてルートで行う必要はありません。

よろしく、 パブロ。

+0

うわー。どのように私はそれを逃すことができる:/。 UrlHelperを処理するためのよりクリーンな方法のようです。いいね、ありがとう! –

+0

こんにちは@Pablo Cibraroはライブサンプルを提供することができますか?私はユニットテストを初めてWeb API用に書いています。 URLヘルパーをどのように利用しているのか、URlヘルパーを使用して排除した質問の中には何があるのか​​は分かりません。どんなヘルプも大歓迎です –