WebAPI的一种单元测试方案

  大家是如何对webApi写测试的呢?
  1.利用Fiddler直接做请求,观察response的内容。
  2.利用Httpclient做请求,断言response的内容。
  3.直接调用webApi的action,这种方式的测试跟真实的调用还是有一定差距,不够完美。
  接下来我介绍一种webApi的in-memory调用方法,也能够达到对webApi的测试,并且由于是in-memory调用,效率也比较高,非常适写 单元测试。本文参考了In memory client, host and integration testing of your Web API service。
  一、首先写一个OrderController用来做测试用
  public class OrderController : ApiController
  {
  // GET api/order
  public Order Get()
  {
  return new Order(){Id = 1,Descriptions = "descriptions",Name = "name"};
  }
  // GET api/order/5
  public string Get(int id)
  {
  return "value";
  }
  // POST api/order
  public Order Post(Order order)
  {
  return order;
  }
  // DELETE api/order/5
  public void Delete(int id)
  {
  }
  }
   二、WebApi的请求过程
  webApi的核心是对消息的管道处理,整个核心是有一系列消息处理器(HttpMessageHandler)首尾连接的双向管道,管道头为HttpServer,管道尾为HttpControllerDispatcher,HttpControllerDispatcher负责对controller的激活和action的执行,然后相应的消息逆向流出管道。
  所以我们可以利用HttpMessageInvoker将一个请求消息HttpRequestMessage发送到管道中,最后收到的消息HttpResponseMessage就代表一个真实的请求响应。
   三、Get请求的测试
  [Test]
  public void GetTest()
  {
  string baseAddress = "http://localhost:33203/";
  HttpConfiguration config = new HttpConfiguration();
  WebApiConfig.Register(config);
  config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
  HttpServer server = new HttpServer(config);
  HttpMessageInvoker messageInvoker = new HttpMessageInvoker(server);
  CancellationTokenSource cts = new CancellationTokenSource();
  HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, baseAddress + "api/order");
  using (HttpResponseMessage response = messageInvoker.SendAsync(request, cts.Token).Result)
  {
  var content = response.Content.ReadAsStringAsync().Result;
  var result = JsonConvert.DeserializeObject<Order>(content);
  result.Name.Should().Be("name");
  }
  }
   四、Post请求的测试
  [Test]
  public void PostTest()
  {
  string baseAddress = "http://localhost:33203/";
  HttpConfiguration config = new HttpConfiguration();
  WebApiConfig.Register(config);
  config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
  HttpServer server = new HttpServer(config);
  HttpMessageInvoker messageInvoker = new HttpMessageInvoker(server);
  CancellationTokenSource cts = new CancellationTokenSource();
  HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, baseAddress + "api/order");
  var order = new Order() { Id = 1, Name = "orderName", Descriptions = "orderDescriptions" };
  request.Content = new ObjectContent<Order>(order, new JsonMediaTypeFormatter());
  using (HttpResponseMessage response = messageInvoker.SendAsync(request, cts.Token).Result)
  {
  var content = JsonConvert.SerializeObject(order, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() });
  response.Content.ReadAsStringAsync().Result.Should().Be(content);
  }
  }

猜你喜欢

转载自www.cnblogs.com/chenlimei/p/9389593.html