.NET6之MiniAPI(二十九):UnitTest
MiniAPI的單元測試與asp.net web?api的單元測試大體是相同的(畢竟都是asp.net core),只是在小細(xì)節(jié)上有一些差異,文章中會(huì)說到這點(diǎn)。
本文測試框架是XUnit,Mock框架是Moq,關(guān)于這兩個(gè)框架和庫的學(xué)習(xí),這里就忽略了。
首先創(chuàng)建兩個(gè)項(xiàng)目,API項(xiàng)目MiniAPI19UnitTest,UnitTest項(xiàng)目MiniAPI19UnitTestUT,如下:
MiniAPI19UnitTest
var?builder?=?WebApplication.CreateBuilder(args); builder.Services.AddScoped<IOrderService, OrderService>(); var app = builder.Build();app.MapGet("/order", (IOrderService orderService) => {return "Result:" + orderService.GetOrder("123"); }); app.MapPost("/order", (Order order, IOrderService orderService) => {return "Result:" + orderService.AddOrder(order); }); app.Run();public interface IOrderService {bool AddOrder(Order order);string GetOrder(string orderNo); } public class OrderService : IOrderService {private readonly ILogger<OrderService> _logger;public OrderService(ILogger<OrderService> logger){_logger = logger;}public string GetOrder(string orderNo){return "this is my order,orderno:" + orderNo;}public bool AddOrder(Order order){_logger.LogInformation(order.ToString());return true;} } public record Order {public string OrderNo { get; set; }public?string?Name?{?get;?set;?}public decimal Price { get; set; } }MiniAPI19UnitTestUT:在本項(xiàng)目中添加引用MiniAPI19UnitTest項(xiàng)目
using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Moq; using System; using System.Net.Http; using System.Threading.Tasks; using?Xunit; namespace MiniAPI19UnitTestUT {public class MiniAPI19Test{????[Fact]//無參測試public async Task GetOrderTest(){var orderNo = "abcd";//用Moq來mock server接口,達(dá)到層的隔離var mock = new Mock<IOrderService>();mock.Setup(x => x.GetOrder(It.IsAny<string>())).Returns(orderNo);var?myapp?=?new?MyAppHostTest(services?=>?services.AddSingleton(mock.Object));var client = myapp.CreateClient();var result = await client.GetStringAsync("/order");Assert.Equal($"Result:{orderNo}",?result);}[Theory]//有參測試[InlineData(true)][InlineData(false)]public async Task PostOrderTest(bool backResult){var mock = new Mock<IOrderService>();mock.Setup(x => x.AddOrder(It.IsAny<Order>())).Returns(backResult);var?myapp?=?new?MyAppHostTest(services?=>?services.AddSingleton(mock.Object));var client = myapp.CreateClient();var?content?=?new?StringContent(System.Text.Json.JsonSerializer.Serialize(new?Order{OrderNo?=?"abcd",Name?=?"Surface?Pro?8",Price?=?10000}),System.Text.Encoding.UTF8,"application/json");var response = await client.PostAsync("/order", content);var result = await response.Content.ReadAsStringAsync();Assert.Equal($"Result:{backResult}", result);}}//本類是加構(gòu)我們MiniAPI web host的類型,封裝后以供測試程序調(diào)用class MyAppHostTest : WebApplicationFactory<Program>{private readonly Action<IServiceCollection> _services;public MyAppHostTest(Action<IServiceCollection> services){_services = services;}protected override IHost CreateHost(IHostBuilder builder){builder.ConfigureServices(_services);return base.CreateHost(builder);}} }上面的代碼會(huì)報(bào)錯(cuò),找不到Program的,這是因?yàn)锳PI項(xiàng)目是用Top Level的方式來開發(fā)的,Program的訪問修飾符是internal,雖然添加引用了MiniAPI19UnitTest項(xiàng)目,但Program是訪問不到的,這里有兩個(gè)解決方案,要么不用Top Level,如下面這樣寫代碼:
public?class?Program {static?void?Main(string[]?args){var?builder?=?WebApplication.CreateBuilder(args);builder.Services.AddScoped<IOrderService,?OrderService>();var?app?=?builder.Build();app.MapGet("/test",?(IOrderService?orderService)?=>{return?"Result:"?+?orderService.GetOrder("123");});app.Run();} }或者在MiniAPI19UnitTest.csproj文件中添加如下配置,讓測試項(xiàng)目能訪問到Program
<ItemGroup><InternalsVisibleTo Include="MiniAPI19UnitTestUT"/></ItemGroup>用反射工具查看API項(xiàng)目結(jié)果如下,Main函數(shù)是Top-Level Entry Point方式,也看不到Program
這時(shí),就可以開心地寫自己的單元測試了。
總結(jié)
以上是生活随笔為你收集整理的.NET6之MiniAPI(二十九):UnitTest的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AgileConfig 1.6.0 发布
- 下一篇: Xamarin效果第二十篇之GIS中加载