ASP.NET CORE 2.* 利用集成测试框架覆盖HttpClient相关代码

ASP.NET CORE 集成测试官方介绍

我的asp.net core 项目里面大部分功能都是去调用别人的API ,大量使用HttpClient,公司单元测试覆盖率要求95%以上,很难做到不mock HttpClient 达到这个指数。

以下方法是我自己总结的在单元测试里 mock httpClient 的方式,基本思路是利用集成测试框架,mock外部调用的API ,达到httpClient 代码的覆盖。

代码地址:https://github.com/Halo-Shaka/LearningAspNetCoreIntegrationTesting.git

举个例子,创建一个简单的asp.net core 项目,里面只有一个api , api/values, 是个get 方法,

get 方法内部是去调用外部API, 随便写个方法  向google 发一个信息。


[Route("api/[controller]")]

 [ApiController]

 public class ValuesController : ControllerBase

 {

     private readonly IHttpClientFactory _httpClientFactory;

     private readonly IOptions<AppSettings> _options;

     public ValuesController(IHttpClientFactory httpClientFactory, IOptions<AppSettings> options)

     {

         _httpClientFactory = httpClientFactory;

         _options = options;

     }

     [HttpGet]

     public async Task<ActionResult> Get()

     {

         var client = _httpClientFactory.CreateClient();

         var url = _options.Value.Url;

         var payload = new

         {

             From = "China"

         };

         var requestMessage = new HttpRequestMessage(HttpMethod.Post, url)

         {

             Content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json")

         };

         try

         {

             var response = await client.SendAsync(requestMessage);

             var content = await response.Content.ReadAsStringAsync();

             if (response.StatusCode == HttpStatusCode.OK)

             {

                 return Ok(content);

             }

             return BadRequest();

         }

         catch (Exception e)

         {

             return StatusCode(502);

         }

     }

 }

这里面有个需要注意的地方,使用注入的httpClient, 外部访问的地址需要是配置的


public class Startup

   {

       public Startup(IConfiguration configuration)

       {

           Configuration = configuration;

       }

       public IConfiguration Configuration { get; }

       public void ConfigureServices(IServiceCollection services)

       {

           services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

           services.AddHttpClient();

       }

       public void Configure(IApplicationBuilder app, IHostingEnvironment env)

       {

           if (env.IsDevelopment())

           {

               app.UseDeveloperExceptionPage();

           }

           else

           {

               app.UseHsts();

           }

           app.UseHttpsRedirection();

           app.UseMvc();

       }

   }

  

到此为止,基本功能就写完了,现在来写测试代码 

添加 XUnit单元测试项目,添加如下包

Microsoft.AspNetCore.App

Microsoft.AspNetCore.Mvc.Testing

Microsoft.NET.Test.Sdk

Moq

利用集成测试的虚拟站点,把我们需要调用的外部API 伪造出来,


MockGatewayData类的作用是 让客户端能够访问到服务端,并指定想要返回的结果
接着创建 GenericWebApplicationFactory,并把刚伪造的 controller 指定到虚拟站点里面,


最后写测试代码


最后看下覆盖率,整个controller 里面httpClient  全都被覆盖了

代码地址:

https://github.com/Halo-Shaka/LearningAspNetCoreIntegrationTesting.git

原文链接:https://www.cnblogs.com/MindSharing/p/11283980.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com