2012-04-06 25 views
18

Có mã mẫu cho thấy đơn vị kiểm tra bộ điều khiển kế thừa từ bộ điều khiển api không? Tôi đang cố gắng để đơn vị kiểm tra một POST nhưng nó không thành công. Tôi tin rằng tôi cần thiết lập HttpControllerContext để thử nghiệm nhưng không biết cách Cảm ơnMã mẫu để kiểm tra đơn vị bộ điều khiển api

+0

Câu hỏi trùng lặp có thể? http://stackoverflow.com/questions/9483663/unit-testing-asp-net-web-api –

Trả lời

10

mã này sẽ chứng minh những điều cơ bản về kiểm tra bài đăng. Giả sử bạn có một kho lưu trữ được tiêm vào bộ điều khiển. Tôi đang sử dụng MVC 4 RC không Beta đây nếu bạn đang sử dụng Beta Request.CreateResponse (... là một chút khác nhau để cung cấp cho tôi một tiếng hét ...

Với mã điều khiển một chút như thế này:

public class FooController : ApiController 
{ 
    private IRepository<Foo> _fooRepository; 

    public FooController(IRepository<Foo> fooRepository) 
    { 
     _fooRepository = fooRepository; 
    } 

    public HttpResponseMessage Post(Foo value) 
    { 
     HttpResponseMessage response; 

     Foo returnValue = _fooRepository.Save(value); 
     response = Request.CreateResponse<Foo>(HttpStatusCode.Created, returnValue, this.Configuration); 
     response.Headers.Location = "http://server.com/foos/1"; 

     return response; 
    } 
} 

Các đơn vị kiểm tra sẽ xem xét một chút như thế này (NUnit và RhinoMock)

 Foo dto = new Foo() { 
      Id = -1, 
      Name = "Hiya" 
     }; 

     IRepository<Foo> fooRepository = MockRepository.GenerateMock<IRepository<Foo>>(); 
     fooRepository.Stub(x => x.Save(dto)).Return(new Foo() { Id = 1, Name = "Hiya" }); 

     FooController controller = new FooController(fooRepository); 

     controller.Request = new HttpRequestMessage(HttpMethod.Post, "http://server.com/foos"); 
     //The line below was needed in WebApi RC as null config caused an issue after upgrade from Beta 
     controller.Configuration = new System.Web.Http.HttpConfiguration(new System.Web.Http.HttpRouteCollection()); 

     var result = controller.Post(dto); 

     Assert.AreEqual(HttpStatusCode.Created, result.StatusCode, "Expecting a 201 Message"); 

     var resultFoo = result.Content.ReadAsAsync<Foo>().Result; 
     Assert.IsNotNull(resultFoo, "Response was empty!"); 
     Assert.AreEqual(1, resultFoo.Id, "Foo id should be set"); 
+0

Bài đăng của bạn vô tình phát hiện ra một lỗi nhỏ trong mã của tôi. Tôi đã để lại tham số thứ ba cho CreateResponse (..., this.Configuration). Ngay khi tôi thêm nó, cấu hình null cho đối tượng yêu cầu của tôi không còn là vấn đề nữa. Hy vọng điều này sẽ giúp người khác đang tìm kiếm – oddmeter

+0

Đặt cấu hình bằng 'controller.Configuration = new System.Web.Http.HttpConfiguration (new System.Web.Http.HttpRouteCollection());' trả về null trong dòng trả lời hành động của tôi, vì vậy tôi đã thử điều này: controller.Request.Properties.Add (HttpPropertyKeys.HttpConfigurationKey, HttpConfiguration mới()); va no đa hoạt động. –

+0

-1 Đó là một số lượng khủng khiếp của mã để đưa vào một bài kiểm tra đơn vị. [Có những công cụ tốt hơn] (http://stackoverflow.com/a/22200520/11635) –

0

tôi đã tạo ra giải pháp chung để gọi một số hành động và nhận được HttpResponseMessage như từ điển mà là rất thuận tiện cho việc sử dụng.

Đầu tiên một số phần mở rộng cho từ điển:

public static class DictionaryExtensions 
{ 
    public static void AddRange<T, S>(this Dictionary<T, S> source, 
             Dictionary<T, S> collection) 
    { 
     if (collection == null) 
     { 
      throw new NullReferenceException("Collection is null"); 
     } 

     foreach (var item in collection) 
     { 
      source.Add(item.Key, item.Value); 
     } 
    } 
} 

Bây giờ yêu cầu tạo một phần:

public class RequestCreator 
{ 
    protected static void FirstPart(ApiController controller, 
            HttpMethod method,String actionUrl) 
    { 
     // Creating basic request message with message type and requesting 
     // url example : 'http://www.someHostName/UrlPath/' 
     controller.Request = new HttpRequestMessage(method, actionUrl); 

     // Adding configuration for request 
     controller.Request.Properties. 
      Add(HttpPropertyKeys.HttpConfigurationKey,new HttpConfiguration());           
    } 

    protected static Dictionary<String, Object> SecondPart 
               (HttpResponseMessage response) 
    { 
     // Adding basic response content to dictionary 
     var resultCollection = new Dictionary<String, Object> 
     { 
      {"StatusCode",response.StatusCode}, 
      {"Headers",response.Headers}, 
      {"Version",response.Version}, 
      {"RequestMessage",response.RequestMessage}, 
      {"ReasonPhrase",response.ReasonPhrase}, 
      {"IsSuccessStatusCode",response.IsSuccessStatusCode} 
     }; 

     var responseContent = response.Content; 
     // If response has content then parsing it and 
     // getting content properties 
     if (null != responseContent) 
     { 
      var resultMessageString = response.Content. 
               ReadAsStringAsync().Result; 
      resultCollection.AddRange((new JavaScriptSerializer()). 
             DeserializeObject(resultMessageString) 
               as Dictionary<String, Object>); 
     } 


     return resultCollection; 
    }  
} 

Và cuối cùng thông điệp phản ứng vào từ điển lớp chuyển đổi:

public class HttpResponseModelGetter : RequestCreator 
{ 
    public Dictionary<String, Object> 
       GetActionResponse(ApiController controller,HttpMethod method, 
          String actionUrl,Func<HttpResponseMessage> callBack) 
    { 
     FirstPart(controller, method, actionUrl); 
     var response = callBack(); 
     return SecondPart(response); 
    } 
} 

public class HttpResponseModelGetter<T> : RequestCreator 
{ 
    public Dictionary<String, Object> 
      GetActionResponse(ApiController controller,HttpMethod method, 
       String actionUrl,Func<T,HttpResponseMessage> callBack,T param) 
    { 
     FirstPart(controller, method, actionUrl); 
     var response = callBack(param); 
     return SecondPart(response); 
    } 
} 

public class HttpResponseModelGetter<T1,T2> : RequestCreator 
{ 
    public Dictionary<String, Object> 
     GetActionResponse(ApiController controller,HttpMethod method, 
      String actionUrl,Func<T1,T2,HttpResponseMessage> callBack, 
      T1 param1,T2 param2) 


    { 
     FirstPart(controller, method, actionUrl); 
     var response = callBack(param1,param2); 
     return SecondPart(response); 
    } 
} 
//and so on... 

và cách dùng:

var responseGetter = new HttpResponseModelGetter(); 
var result = responseGetter.GetActionResponse(controller,HttpMethod.Get, 
        "http://localhost/Project/api/MyControllerApi/SomeApiMethod", 
               controller.SomeApiMethod); 

Boolean isComplete = Boolean.Parse(result["isComplete"].ToString()); 
1

Sử dụng AutoFixture, tôi thường làm một cái gì đó như thế này:

[Theory, AutoCatalogData] 
public void PostToCollectionReturnsCorrectResponse(
    CategoriesController sut, 
    CategoryRendition categoryRendition) 
{ 
    HttpResponseMessage response = sut.Post(categoryRendition); 

    Assert.Equal(HttpStatusCode.Created, response.StatusCode); 
} 

Xem this other SO answer để biết thêm chi tiết về phương pháp này. đang

+0

@Downvoter Chăm sóc để giải thích vấn đề? –

0

mẫu cho bộ điều khiển kiểm tra đơn vị API với async fundtion trong C#

  1. Chuẩn bị mô hình thử nghiệm:

     using System; 
         namespace TestAPI.Models 
         { 
          public class TestResult 
          { 
           public DateTime Date { get; set; } 
           public bool Success { get; set; } 
           public string Message { get; set; } 
          }  
         } 
    
  2. Chuẩn bị điều khiển kiểm tra

     using TestAPI.Models; 
         using System; 
         using System.Net; 
         using System.Threading.Tasks; 
         using System.Web.Http; 
         using System.Web.Http.Description; 
    
         namespace TestAPI.Controllers 
         { 
          public class TestController : ApiController 
          {  
           public TestController() 
           {   
           } 
    
           [HttpPost] 
           [ResponseType(typeof(TestResult))] 
           [Route("api/test/start")] 
           public async Task<IHttpActionResult> StartTest() 
           {         
            DateTime startTime = DateTime.Now; 
            var testProcessor = new TestAsync(); 
            await testProcessor.StartTestAsync();          
    
            HttpStatusCode statusCode = HttpStatusCode.OK; 
            return Content(statusCode, new TestResult 
            { 
             Date = DateTime.Now, 
             Success = true, 
             Message = "test" 
            }); 
           }  
    
          } 
         } 
    
  3. đơn vị điều khiển kiểm tra async với kết quả kiểm tra từ phản ứng

     using Microsoft.VisualStudio.TestTools.UnitTesting; 
         using TestAPI.Controllers; 
         using TestAPI.Models; 
         using System.Web.Http; 
         using System.Threading.Tasks; 
         using System.Net; 
         using System.Web.Script.Serialization; 
    
         namespace Unit.Tests.Controllers 
         { 
          /// <summary> 
          /// Summary description for ControllerTest 
          /// </summary> 
          [TestClass] 
          public class ControllerTest 
          { 
           private TestController _testController;  
           [TestInitialize] 
           public void estAPI_Initializer() 
           { 
            _testController = new TestController(); 
            var configuration = new HttpConfiguration(); 
            System.Net.Http.HttpRequestMessage request = new System.Net.Http.HttpRequestMessage(); 
            request.Headers.Add("Authorization", "Bearer 1232141241"); 
            request.Headers.Add("ContentType", "application/json"); 
            _testController.Request = request; 
            _testController.Configuration = configuration;    
           } 
    
           [TestCategory("Unit test")] 
           [TestMethod] 
           public async Task API_Async_Controller_Test() 
           { 
            IHttpActionResult asyncResponse = await _testController.StartTest(); 
            var cToken = new System.Threading.CancellationToken(true);   
            var rResult = asyncResponse.ExecuteAsync(cToken);      
            Assert.IsNotNull(rResult); 
            Assert.IsNotNull(rResult.Result); 
            Assert.AreEqual(rResult.Result.StatusCode, HttpStatusCode.OK); 
            Assert.IsNotNull(rResult.Result.Content); 
            var rContent = rResult.Result.Content; 
    
            string data = await rContent.ReadAsStringAsync(); 
            Assert.IsNotNull(data); 
            JavaScriptSerializer JSserializer = new JavaScriptSerializer(); 
            var finalResult = JSserializer.Deserialize<TestResult>(data); 
    
            Assert.IsNotNull(finalResult); 
            Assert.IsTrue(finalResult.Success); 
           }   
          } 
         } 
    
Các vấn đề liên quan