wordpress门户网站,运营推广是什么工作,网站上的图片怎么做,Wordpress可以卸载吗还记得 .NET Framework 的 ASP.NET WebForm 吗#xff1f;那个年代如果要在 Web 层做单元测试简直就是灾难啊。.NET Core 吸取教训#xff0c;在设计上考虑到了可测试性#xff0c;就连 ASP.NET Core 这种 Web 或 API 应用要做单元测试也是很方便的。其中面向接口和依赖注入… 还记得 .NET Framework 的 ASP.NET WebForm 吗那个年代如果要在 Web 层做单元测试简直就是灾难啊。.NET Core 吸取教训在设计上考虑到了可测试性就连 ASP.NET Core 这种 Web 或 API 应用要做单元测试也是很方便的。其中面向接口和依赖注入在这方面起到了非常重要的作用。本文就来手把手教你如何用 xUnit 对 ASP.NET Core 应用做单元测试。.NET Core 常用的测试工具还有 NUnit 和 MSTest我本人习惯用 xUnit 作为测试工具所以本文用的是 xUnit。创建示例项目先用 ASP.NET Core API 模板建一个应用。模板为我们自动创建了一个 ValuesController为了方便演示我们只留其中一个 Get 方法public class ValuesController : ControllerBase{ // GET api/values/5 [HttpGet({id})] public ActionResultstring Get(int id) { return value; }}然后再添加一个 xUnit 单元测试项目模板自动为我们添加好了 xUnit 引用ItemGroup PackageReference IncludeMicrosoft.NET.Test.Sdk Version15.9.0 / PackageReference Includexunit Version2.4.0 / PackageReference Includexunit.runner.visualstudio Version2.4.0 //ItemGroup但要测试 ASP.NET Core 应用还需要添加两个 NuGet 包Install-Package Microsoft.AspNetCore.AppInstall-Package Microsoft.AspNetCore.TestHost当然还要引入目标项目。最后的引用是这样的 ItemGroup PackageReference IncludeMicrosoft.AspNetCore.App Version2.1.5 / PackageReference IncludeMicrosoft.AspNetCore.TestHost Version2.1.1 / PackageReference IncludeMicrosoft.NET.Test.Sdk Version15.9.0 / PackageReference Includexunit Version2.4.0 / PackageReference Includexunit.runner.visualstudio Version2.4.0 / /ItemGroup ItemGroup ProjectReference Include..\WebApplication1\WebApplication1.csproj / /ItemGroup添加完引用后编译一下编译一下确认引用没有问题。编写单元测试写单元测试一般有三个步骤ArrangeAct 和 Assert。Arrange 是准备阶段这个阶段是准备工作比如模拟数据、初始化对象等Act 是行为阶段这个阶段是用准备好的数据去调用要测试的方法Assert 是断定阶段就是把调用目标方法返回的值和预期的值进行比较如果和预期一致说明测试通过否则为失败。按照这个步骤我们来编写一个单元测试方法以 ValuesController 中的 Get 方法作为要测试的目标。一般一个单元测试方法就是一个测试用例。我们在测试工程添加一个 ValuesTests 单元测试类然后编写一个单元测试方法代码如下public class ValuesTests{ public ValuesTests() { var server new TestServer(WebHost.CreateDefaultBuilder() .UseStartupStartup()); Client server.CreateClient(); } public HttpClient Client { get; } [Fact] public async Task GetById_ShouldBe_Ok() { // Arrange var id 1; // Act var response await Client.GetAsync($/api/values/{id}); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); }}这里我们通过 TestServer 拿到一个 HttpClient 对象用它我们可以模拟 Http 请求。我们写了一个非常简单的测试用例完整演示了单元测试的 ArrangeAct 和 Assert 三个步骤。建议单元测试的方法名使用“什么应该是什么”的模式。比如上面的 GetById_ShouldBe_Ok表示调用 GetById 这个 API 返回的结果应该是 OK 的这样一看就知道你这个测试用例是干吗的不需要过多的注释。运行单元测试单元测试用例写好后打开“Test Explore”中文版 VS 看到的是中文在测试方法上右击选择“Run Seleted Tests”也可以在方法代码块内鼠标右击选择“Run Tests”注意看测试方法前面图标的颜色目前是蓝色的表示测试用例还没有运行过。测试用例执行结束后如果结果和预期一致就是绿色的图标如果运行结果和预期不一致就会是红色图标然后你需要修改代码直到出现绿色图标。你可以在“Test Explore”的下方看到执行消耗的时间也可以在 Output 窗口看到执行的细节。以上图标颜色的变化过程是蓝色红色再绿色有可能蓝色经过一次运行就直接变成绿色也有可能经过很多次红色才变成绿色。测试驱动开发中的BRG蓝红绿术语就是这么来的。调试单元测试你可以通过添加断点的方式在单元测试中调试。方法很简单在需要调试的方法上右键选择“Debug Seleted Tests”即可和平时的调试是一样的。如果我们要查看 API 具体返回了什么可以通过加断点调试来查看返回结果的变量字符串值但这种方式不是最好的选择。比如对于同一个 API我要看看 10 种参数返回的结果是什么样的每次都通过断点调试来查看就很麻烦。除了添加断点来调试还有一种打印日志的方法来快速调试xUnit 可以很方便地做到这一点。为此我们来修改一下 ValuesTestspublic ValuesTests(ITestOutputHelper outputHelper){ var server new TestServer(WebHost.CreateDefaultBuilder() .UseStartupStartup()); Client server.CreateClient(); Output outputHelper;}public ITestOutputHelper Output{ get; }// ... (省略其它代码)这里我们在构造函数中添加了 ITestOutputHelper 参数xUnit 会将一个实现此接口的实例注入进来。拿到这个实例后我们就可以用它来输出日志了 [Fact] public async Task GetById_ShouldBe_Ok() { // Arrange var id 1; // Act var response await Client.GetAsync($/api/values/{id}); // Output var responseText await response.Content.ReadAsStringAsync(); Output.WriteLine(responseText); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); }运行注意不是 Debug此方法运行结束后在“Test Explore”的下方可以可以看到“Output”字样点击它就可以看到输出的结果如图通过这种方式每次运行测试我们就可以很方便的查看输出结果了。其它上面我们是通过模拟 Http 请求的方式来调用 API 测试的还有一种就是 new 一个 Controller 来直接调用它的 Action 方法来测试。比如这样 // Arrange var id 1; var controller new ValuesController(); // Act var result controller.Get(id);如果 Controller 没有其它依赖这种方式当然是最方便的。但通常 Controller 是会有一个或多个依赖的比如这样public class ValuesController : Controller{ private readonly ISessionRepository _sessionRepository; public ValuesController(ISessionRepository sessionRepository) { _sessionRepository sessionRepository; } // ...}我们就要模拟实例化这个 Controller 的所有依赖当然手动模拟是不现实的因为一个依赖类还可能会依赖其它的类或接口依赖链可能很长你不可能每个依赖都手动去实例化它们。有一个叫 Moq 的工具可以自动来模拟实例化依赖它的用法是这样的// ..// Arrangevar mockRepo new MockISessionRepository();mockRepo.Setup(...);var controller new HomeController(mockRepo.Object);// Actvar result await controller.Index();这种方式我是不推荐的因为抛开 Moq 的学习成本不说重要的是它不如模拟 Http 请求那样接近真实的调用场景所以本文对它不作过多的介绍大家知道有这么回事就行。