使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(九)-- 单元测试
2016-07-31 23:44
1116 查看
第一部分、XUnit
修改 Project.json 文件内容,增加XUnit相关的nuget包引用,并修改部分配置。{ "version": "1.0.0-*", "testRunner": "xunit", // 设置测试工具为xunit "buildOptions": { "debugType": "portable", "emitEntryPoint": true }, "dependencies": { "Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0" }, "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", "Microsoft.Extensions.Logging.Filter": "1.0.0", "NLog.Extensions.Logging": "1.0.0-rtm-alpha2", "Autofac.Extensions.DependencyInjection": "4.0.0-rc3-309", "Microsoft.Extensions.Configuration": "1.0.0", "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", "xunit": "2.2.0-beta2-build3300", "dotnet-test-xunit": "2.2.0-preview2-build1029" }, "frameworks": { "netcoreapp1.0": { // 设置兼容框架 "imports": [ "dotnet54", "portable-net45+win8" ] } } }
增加一个Demo类和一个测试类
namespace WebApiFrame { public class DemoModel { public int Add(int a, int b) { return a + b; } public bool IsOdd(int num) { return num % 2 == 1; } } }
using Xunit; namespace WebApiFrame.Test { public class DemoModelTest { private readonly DemoModel _demo; public DemoModelTest() { _demo = new DemoModel(); } [Fact] public void AddTest() { int result = _demo.Add(1, 2); Assert.Equal(3, result); } } }
打开cmd窗口,进入到项目根目录,输入命令 dotnet test ,将启动单元测试,可以在输出查看测试结果
using System; using Microsoft.AspNetCore.Mvc; using WebApiFrame.Models; using WebApiFrame.Repositories; namespace WebApiFrame.Controllers { [Route("api/[controller]")] public class UsersController : Controller { private readonly IUserRepository userRepository; public UsersController(IUserRepository userRepo) { userRepository = userRepo; } [HttpGet] public IActionResult GetAll() { var list = userRepository.GetAll(); return new ObjectResult(list); } [HttpGet("{id}")] public IActionResult Get(int id) { var user = userRepository.GetById(id); return new ObjectResult(user); } #region 其他方法 // ...... #endregion } }
UsersController.cs
我们要对 UsersController.cs 的方法进行单元测试,同时UserRepository实例是通过构造函数依赖注入的,所以要借助Moq来模拟这个实例的生成。
在引入Moq包之前,先要修改NuGet.Config配置文件,增加package包源地址。
NuGet.Config配置文件路径: C:\Users\{user}\AppData\Roaming\NuGet
<?xml version="1.0" encoding="utf-8"?> <configuration> <activePackageSource> <add key="nuget.org" value="https://www.nuget.org/api/v2/" /> </activePackageSource> <packageSources> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" /> <!-- 增加的程序包源地址 --> <add key="aspnet-contrib" value="https://www.myget.org/F/aspnet-contrib/api/v3/index.json" /> </packageSources> </configuration>
引入Moq相关nuget包: "moq.netcore": "4.4.0-beta8"
添加单元测试类
using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc; using Moq; using WebApiFrame.Controllers; using WebApiFrame.Models; using WebApiFrame.Repositories; using Xunit; namespace WebApiFrame.Test { public class UsersControllerTest { private readonly UsersController _controller; public UsersControllerTest() { var mockRepo = new Mock<IUserRepository>(); mockRepo.Setup(repo => repo.GetAll()).Returns(GetUsers()); _controller = new UsersController(mockRepo.Object); } [Fact] public void GetAllTest() { IActionResult actionResult = _controller.GetAll(); var objectResult = Assert.IsType<ObjectResult>(actionResult); var result = Assert.IsAssignableFrom<IEnumerable<User>>(objectResult.Value); Assert.Equal(3, result.Count()); } private IEnumerable<User> GetUsers() { return new List<User>() { new User(){ Id = 1, Name = "name:1", Sex = "Male" }, new User(){ Id = 2, Name = "name:2", Sex = "Female" }, new User(){ Id = 3, Name = "name:3", Sex = "Male" }, }; } } }
在cmd窗口执行单元测试,查看测试结果
在一个分层结构清晰的项目里,各层之间依赖于事先约定好的接口。在多人协作开发时,大多数人都只会负责自己的那一部分模块功能,开发进度通常情况下也不一致。当某个开发人员需要对自己的模块进行单元测试而依赖的其他模块还没有开发完成时,则需要对依赖的接口通过Mock的方式提供模拟功能,从而达到在不实际依赖其他模块的具体功能的情况下完成自己模块的单元测试工作。
第三部分、集成测试
以上的例子只是对逻辑进行了单元测试。对于Asp.Net Core项目,还需要模拟在网站部署的情况下对各个请求入口进行测试。通常情况下可以借助Fiddler等工具完成,在.Net Core里也可以用编程的方式完成测试。首先引入测试需要的nuget包。因为我们测试的是WebApi接口,响应内容都是json格式的字符串,所以还需要引用json序列化的nuget包。
"Microsoft.AspNetCore.TestHost": "1.0.0", "Newtonsoft.Json": "9.0.1"
添加测试类
using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.TestHost; using Newtonsoft.Json; using WebApiFrame.Models; using Xunit; namespace WebApiFrame.Test { public class WebApiFrameTest { private readonly TestServer _server; private readonly HttpClient _client; public WebApiFrameTest() { _server = new TestServer(new WebHostBuilder().UseStartup<Startup>()); _client = _server.CreateClient(); } [Fact] public async Task GetAllTest() { var response = await _client.GetAsync("/api/users"); response.EnsureSuccessStatusCode(); var responseString = await response.Content.ReadAsStringAsync(); IList<User> users = JsonConvert.DeserializeObject<IList<User>>(responseString); Assert.Equal(3, users.Count); } [Theory] [InlineData(1)] [InlineData(2)] [InlineData(3)] public async Task GetTest(int id) { var response = await _client.GetAsync($"/api/users/{id}"); response.EnsureSuccessStatusCode(); var responseString = await response.Content.ReadAsStringAsync(); User user = JsonConvert.DeserializeObject<User>(responseString); Assert.NotNull(user); } } }
在cmd窗口执行单元测试,查看测试结果
在上面的例子里,通过在一个工程里同时模拟了服务端(TestServer)和客户端(HttpClient)的通信,从而达到了整体测试WebApi接口的目的。
相关文章推荐
- Asp.net项目因Session阻塞导致页面打开速度变慢
- ASP.NET中常用的几个李天平开源公共类LTP.Common,Maticsoft.DBUtility,LtpPageControl
- ASP.net Core部署说明(Ubuntu) [转]
- Asp.Net MVC session跨域
- Asp.net 使用 Jsonp
- ASP.NET MVC中加入Web Forms
- [Asp.net]SignalR实现实时日志监控
- Swashbuckle for asp.net core 配置说明
- java8之Metaspace
- 如何在asp.net页面使用css和js
- 任意文件下载漏洞 asp站点
- 任意文件下载漏洞 aspx站点
- ASP.NET ZERO 学习 导航菜单
- 【嵌入式开发】Raspberry Pi 树莓派性能测试
- 使用Visual Studio 2015 开发ASP.NET MVC 5 项目部署到Mono/Jexus
- 关于在ASP.NET MVC 中使用EF的Code First的方式来读取数据库时的Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
- Spring Mvc那点事---(34)Spring事务基于AspectJ实现
- ASP.NET MVC4 NInject 使用示例教程
- 【Dongle】【ASP.NET】Web总结(二)
- 使用Visual Studio 2015 开发ASP.NET MVC 5 项目部署到Mono/Jexus