本篇将结合这个系列的例子的基础上演示在Asp.Net Core里如何使用XUnit结合Moq进行单元测试,同时对整个项目进行集成测试。
修改 Project.json 文件内容,增加XUnit相关的nuget包引用,并修改部分配置。
1 { 2 "version": "1.0.0-*", 3 "testRunner": "xunit", // 设置测试工具为xunit 4 5 "buildOptions": { 6 "debugType": "portable", 7 "emitEntryPoint": true 8 }, 9 "dependencies": { 10 "Microsoft.NETCore.App": { 11 "type": "platform", 12 "version": "1.0.0" 13 }, 14 "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", 15 "Microsoft.AspNetCore.Mvc": "1.0.0", 16 "Microsoft.Extensions.Logging": "1.0.0", 17 "Microsoft.Extensions.Logging.Console": "1.0.0", 18 "Microsoft.Extensions.Logging.Debug": "1.0.0", 19 "Microsoft.Extensions.Logging.Filter": "1.0.0", 20 "NLog.Extensions.Logging": "1.0.0-rtm-alpha2", 21 "Autofac.Extensions.DependencyInjection": "4.0.0-rc3-309", 22 "Microsoft.Extensions.Configuration": "1.0.0", 23 "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", 24 "Microsoft.Extensions.Configuration.Json": "1.0.0", 25 "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", 26 "xunit": "2.2.0-beta2-build3300", 27 "dotnet-test-xunit": "2.2.0-preview2-build1029" 28 }, 29 "frameworks": { 30 "netcoreapp1.0": { 31 // 设置兼容框架 32 "imports": [ 33 "dotnet54", 34 "portable-net45+win8" 35 ] 36 } 37 } 38 }
增加一个Demo类和一个测试类
1 namespace WebApiFrame 2 { 3 public class DemoModel 4 { 5 public int Add(int a, int b) 6 { 7 return a + b; 8 } 9 10 public bool IsOdd(int num) 11 { 12 return num % 2 == 1; 13 } 14 } 15 }
1 using Xunit; 2 3 namespace WebApiFrame.Test 4 { 5 public class DemoModelTest 6 { 7 private readonly DemoModel _demo; 8 9 public DemoModelTest() 10 { 11 _demo = new DemoModel(); 12 } 13 14 [Fact] 15 public void AddTest() 16 { 17 int result = _demo.Add(1, 2); 18 Assert.Equal(3, result); 19 } 20 } 21 }
打开cmd窗口,进入到项目根目录,输入命令 dotnet test ,将启动单元测试,可以在输出查看测试结果
再对另外一个方法添加单元测试代码
1 [Theory] 2 [InlineData(1)] 3 [InlineData(2)] 4 [InlineData(3)] 5 public void IsOdd(int num) 6 { 7 bool result = _demo.IsOdd(num); 8 Assert.True(result, $"{num} is not odd."); 9 }
再次启动单元测试,查看测试结果
结果显示执行了四个单元测试用例,有一个失败了。
通过比较上面两个测试方法可以发现使用的特性标识不同,测试方法的参数列表也不相同。
[Face]特性标识表示固定输入的测试用例,而[Theory]特性标识表示可以指定多个输入的测试用例,结合InlineData特性标识使用。在上面的例子里,总共使用了三次InlineData特性标识,每次设定的值都不同,在执行单元测试时,设定的值会被测试框架赋值到对应的测试方法的参数里。
第二部分、Moq
在之前的例子里已经定义了如下接口和类
1 using System.Collections.Generic; 2 using WebApiFrame.Models; 3 4 namespace WebApiFrame.Repositories 5 { 6 public interface IUserRepository 7 { 8 IEnumerable<User> GetAll(); 9 10 User GetById(int id); 11 } 12 }