2016-07-14 13 views
2

私はwebapiを習得しようとしており、問題を遭遇しました。私がやっていたトレーニングコースでは、次と前のリンクで応答ヘッダーを返すことによってページングを行う方法を示しました。ただし、HttpContext.Current.Response.Headers.Add()を使用して、次のリンク、前のリンク、および合計ページを送り返します。レスポンスヘッダー付きのユニットテストwebapiコントローラ

また、コントローラの単体テストを実装しようとしています。問題は、ユニットテストを実行しているときにHttpContext.Currentnullであると思われます。私はどこかで、私は012au testapではないのでwebapiのためにHttpContext.Currentではないはずですが、私は代わりに何を使用すべきか分かりません。

public partial class CandidateManagerController 
{ 
    private readonly ICandidateManager _candidateManagerV2; 

    public CandidateManagerController(ICandidateManager candidateManager) 
    { 
     _candidateManagerV2 = candidateManager; 
    } 

    [VersionedRoute("CandidateManager", 2, Name="CandidateManagerV2")] 
    public IHttpActionResult Get(int page = 1, int pageSize = 1) 
    { 
     try 
     { 
      var totalCount = 0; 
      var totalPages = 0; 

      var result = _candidateManagerV2.GetCandidates(out totalCount, out totalPages, page, pageSize); 

      var urlHelper = new UrlHelper(Request); 


      var prevLink = page > 1 
       ? urlHelper.Link("CandidateManagerV2", 
        new 
        { 
         page = page - 1, 
         pageSize = pageSize, 
        }) 
       : ""; 


      var nextLink = page < totalPages ? urlHelper.Link("CandidateManagerV2", 
       new 
       { 
        page = page + 1, 
        pageSize = pageSize 
       }) : ""; 

      var paginationHeader = new 
      { 
       currentPage = page, 
       pageSize = pageSize, 
       totalCount = totalCount, 
       totalPages = totalPages, 
       previousPageLink = prevLink, 
       nextPageLink = nextLink 
      }; 

      HttpContext.Current.Response.Headers.Add("X-Pagination", Newtonsoft.Json.JsonConvert.SerializeObject(paginationHeader)); 



      return Ok(result); 
     } 
     catch (Exception exp) 
     { 
      return InternalServerError(); 
     } 
    } 

} 

は、ここに私のユニットテストです:

は、ここに私のcontollerコードです。私はNunitとMoqを使用していることに注意してください。

[TestFixture] 
public class CandidateManagerControllerV2Tests 
{ 


    [Test] 
    [Category("CandidateManagerController Unit Tests")] 
    public void Should_Return_List_Of_Candidate_Objects() 
    { 

     var testList = new List<Candidate>(); 
     testList.Add(new Candidate() { CandidateId = 1, Name = "Mr", Surname = "Flibble" }); 
     testList.Add(new Candidate() { CandidateId = 2, Name = "Arnold", Surname = "Rimmer" }); 

     var totalCount = 0; 
     var totalPages = 0; 
     var mockManager = new Mock<ICandidateManager>(); 
     mockManager.Setup(x => x.GetCandidates(out totalCount, out totalPages, It.IsAny<int>(), It.IsAny<int>())).Returns(testList); 

     var controller = new CandidateManagerController(mockManager.Object); 
     SetupControllerForTests(controller); 

     var result = controller.Get(1, 1); 
    } 

    private static void SetupControllerForTests(ApiController controller) 
    { 
     var config = new HttpConfiguration(); 
     var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/candidatemanager"); 
     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; 
     controller.ActionContext=new HttpActionContext(); 
    } 

} 

私は誰かが私を助けてくれることを望んでいます。ページングを実装する方法を間違った方向に導いてきた可能性があります。しかし、何らかの理由でレスポンスヘッダーを追加する必要がある可能性があります。

+0

HttpContextをモックアップしないでください。代わりにメモリ内統合テストを作成します。例:http://stephenzeng.com/Home/View/17を参照してください。 –

答えて

0

HttpContextに自分自身を結合しないでください。

ヘッダーを設定して、意図したとおりに単体テストできるようにするもう1つのアプローチはここにあります。あなたはHttpResponseMessageを作成し、必要に応じてヘッダを追加し、それからResponseMessageResultを作成します。

//...code removed for brevity 

var response = Request.CreateResponse(HttpStatusCode.OK, result); 

response.Headers.Add("X-Pagination", Newtonsoft.Json.JsonConvert.SerializeObject(paginationHeader)); 

IHttpActionResult ok = ResponseMessage(response); 

return ok; 

あなたは、コントローラのをリセットしているので、あなたはまた、あなたのUrlHelperを作成するときに、あなたのコントローラのセットアップがnull参照エラーが発生することに注意すべきですnullにRequestあなたがデフォルトにActionContext

private static void SetupControllerForTests(ApiController controller) { 
    var config = new HttpConfiguration(); 
    var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/candidatemanager"); 
    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; 
    //commented this out as it was causing Request to be null 
    //controller.ActionContext=new HttpActionContext(); 
} 

を割り当てるX-Paginationヘッダ

をチェックするときに渡され、次のテスト0
public async Task Should_Return_Paged_List_Of_Candidate_Objects() { 
    //Arrange 
    var testList = new List<Candidate>(); 
    testList.Add(new Candidate() { CandidateId = 1, Name = "Mr", Surname = "Flibble" }); 
    testList.Add(new Candidate() { CandidateId = 2, Name = "Arnold", Surname = "Rimmer" }); 

    var totalCount = 0; 
    var totalPages = 0; 
    var mockManager = new Mock<ICandidateManager>(); 
    mockManager.Setup(x => x.GetCandidates(out totalCount, out totalPages, It.IsAny<int>(), It.IsAny<int>())).Returns(testList); 

    var controller = new CandidateManagerController(mockManager.Object); 
    SetupControllerForTests(controller); 

    //Act 
    var response = await controller.Get(1, 1).ExecuteAsync(System.Threading.CancellationToken.None); 

    //Assert 
    Assert.IsNotNull(response); 
    Assert.IsInstanceOfType(response, typeof(HttpResponseMessage)); 
    Assert.IsTrue(response.Headers.Contains("X-Pagination")); 
} 
+0

要求がストリームなどを保持している場合、どうすればこのようにテストできますか?マルチパートコンテキスト。私はこのようにテストしたいと思いますが、メモリHttpServerを使用して終了しました。要求は現実の状況のように処理されます。 – ntohl

+0

@ntohlは、テスト中のシステムを実行するために必要なものを要求に埋め込みます。リクエストのContentプロパティをそれに応じて設定します。 – Nkosi

+0

私はそれを管理しました。ありがとう。しかしCORSを平等に追加した後、ヘッダーが '[EnableCors(" Origin "、" POST ")]'から正しく生成されているかどうかチェックしなければなりませんでした。またカスタムMessageHandler応答にした。 – ntohl

関連する問題