ASP.NET 5 使用 TestServer 进行单元测试
之前如果对 ASP.NET WebAPI 进行单元测试(HttpClient 发起请求,并且可调试 WebAPI),一般采用 Owin 的方式,具体参考:《开发笔记:用 Owin Host 实现脱离 IIS 跑 Web API 单元测试》
示例代码:
public class ValuesWebApiTest : IDisposable
{
private const string HOST_ADDRESS = "http://localhost:8001";
private IDisposable _webApp;
private HttpClient _httClient;
public AdTextUnitWebApiTest()
{
_webApp = WebApp.Start<Startup>(HOST_ADDRESS);
Console.WriteLine("Web API started!");
_httClient = new HttpClient();
_httClient.BaseAddress = new Uri(HOST_ADDRESS);
Console.WriteLine("HttpClient started!");
}
[Fact]
public async Task Get()
{
var response = await _httClient.GetAsync("/api/values");
if (response.StatusCode != HttpStatusCode.OK)
{
Console.WriteLine(response.StatusCode);
Console.WriteLine((await response.Content.ReadAsAsync<HttpError>()).ExceptionMessage);
}
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var test = await response.Content.ReadAsStringAsync();
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
public void Dispose()
{
_httClient.Dispose();
_webApp.Dispose();
}
}
本来想在 ASP.NET 5 WebAPI 项目中,也用这一套测试代码,但发现并不适用,因为 ASP.NET WebAPI 2 和 ASP.NET 5 WebAPI 并不是特别一样,比如 Startup.cs 的配置等等,之前使用 WebApp.Start<Startup>(HOST_ADDRESS)
的方式启动 WebAPI 项目,而 ASP.NET 5 WebAPI 变成了这样的:
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
想用 WebApplication.Run
的方式替换掉 WebApp.Start
,但发现并不可行,比如 args 的参数问题,自己想的有点简单了,后来 Google 搜索了一些资料,发现 ASP.NET 5 增加了 TestServer,自己找资料配置了很久,看别人的示例代码很简单,但我运行的时候就是各种报错,主要原因是程序包的版本不对,因为我是按照 project.json 的提示安装的,比如 Microsoft.AspNet.TestHost
这个程序包,提示最新版本为 1.0.0-rc2-15960
,并且没有 1.0.0-rc1-final
版本,然后我就安装提示安装的 rc2,就报下面的异常:
异常信息:Could not load type 'Microsoft.AspNet.Builder.RequestDelegate' from assembly 'Microsoft.AspNet.Http.Abstractions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
根据提示,我以为异常原因是没有加载 Microsoft.AspNet.Http.Abstractions
程序集,然后又添加此程序集,重新运行发现还是报错。。。后面具体的过程就不记录了,反正坑很大,根本原因是 Microsoft.AspNet.TestHost
程序包的版本不对,应该安装 1.0.0-rc1-final
版本,我是后来无意间重启 VS2015 发现的。
下面贴一下 ASP.NET 5 进行单元测试的一些代码。
首先 ASP.NET 5 WebAPI 项目 Startup.cs 配置代码:
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Demo.WebApi
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseIISPlatformHandler();
app.UseStaticFiles();
app.UseMvc();
}
// Entry point for the application.
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
}
ValuesWebApiTest 测试代码:
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Demo.WebApiTests
{
public class ValuesWebApiTest
{
public TestServer _server;
public ValuesWebApiTest()
{
_server = TestServer.Create(app =>
{
var env = app.ApplicationServices.GetRequiredService<IHostingEnvironment>();
var loggerFactory = app.ApplicationServices.GetRequiredService<ILoggerFactory>();
new CNBlogs.Ad.WebApi.Startup(env).Configure(app, env, loggerFactory);
}, services =>
{
services.AddMvc();
services.Configure();
});
}
}
[Fact]
public async Task Get()
{
var response = await _server.CreateClient().GetAsync("/api/values");
if (response.StatusCode != HttpStatusCode.OK)
{
Console.WriteLine(response.StatusCode);
Console.WriteLine((await response.Content.ReadAsAsync<HttpError>()).ExceptionMessage);
}
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var test = await response.Content.ReadAsStringAsync();
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}
project.json 配置代码:
{
"frameworks": {
"dnx451": { }
},
"dependencies": {
"Microsoft.AspNet.Mvc.WebApiCompatShim": "6.0.0-rc1-final",
"Microsoft.Net.Http": "2.2.29",
"Microsoft.AspNet.TestHost": "1.0.0-rc1-final",
"xunit": "2.1.0",
"xunit.runner.dnx": "2.1.0-rc1-build204"
},
"commands": {
"test": "xunit.runner.dnx"
}
}
运行测试成功,并且可以 Debug 调试,需要注意 using 引用(没用的我都去掉了),还有程序包的版本号。
注:如果 VS2015 Test Explorer 中找不到测试示例,需要安装最新的 xUnit 程序包。
"xunit": "2.2.0-beta2-build3256",
"xunit.runner.dnx": "2.1.0-rc2-build209"
xUnit 程序包地址:http://myget.org/gallery/xunit
参考资料:
- Integration testing ASP.NET 5 and ASP.NET MVC 6 applications | StrathWeb. A free flowing web tech monologue.
- Writing integration tests for ASP.NET 5
- Testing asp.net 5 vnext middleware from a TestServer - Stack Overflow
ASP.NET 5 使用 TestServer 进行单元测试的更多相关文章
- asp.net core 使用 TestServer 来做集成测试
asp.net core 使用 TestServer 来做集成测试 Intro 之前我的项目里的集成测试是随机一个端口,每次都真实的启动一个 WebServer,之前也有看到过微软文档上 TestSe ...
- ASP.NET Core 对Controller进行单元测试
单元测试对我们的代码质量非常重要.很多同学都会对业务逻辑或者工具方法写测试用例,但是往往忽略了对Controller层写单元测试.我所在的公司没见过一个对Controller写过测试的.今天来演示下如 ...
- Asp.Net MVC3中如何进行单元测试?
下面我们就以一个示例演示一下如何进行单元测试? public Model.UserInfo UpdateEntity(Model.UserInfo entity) { db.UserInfo.Atta ...
- ASP.NET 5 单元测试中使用依赖注入
相关博文:<ASP.NET 5 使用 TestServer 进行单元测试> 在上一篇博文中,主要说的是,使用 TestServer 对 ASP.NET 5 WebApi 进行单元测试,依赖 ...
- 单元测试 – ASP.NET MVC 4 系列
在开发可测试软件的过程中,单元测试已成为确保软件质量的一个不可或缺部分.测试驱动开发(Test-Driven Development,TDD)是编写单元测试的一种方法,采用该方法的开发人 ...
- Asp.Net Core 单元测试正确姿势
背景 ASP.NET Core 支持依赖关系注入 (DI) 软件设计模式,并且默认注入了很多服务,具体可以参考 官方文档, 相信只要使用过依赖注入框架的同学,都会对此有不同深入的理解,在此无需赘言. ...
- ASP.NET Core 入门(3)(单元测试Xunit及Shouldly的使用)
一.本篇简单介绍下在ASP.NET Core项目如何使用单元测试,例子是使用VS自带的Xunit来测试Web API接口,加上一款开源的断言工具Shouldly,方便写出更简洁.可读行更好的测试代码. ...
- Asp.Net Core 轻松学-利用xUnit进行主机级别的网络集成测试
前言 在开发 Asp.Net Core 应用程序的过程中,我们常常需要对业务代码编写单元测试,这种方法既快速又有效,利用单元测试做代码覆盖测试,也是非常必要的事情:但是,但我们需要对系统进行集 ...
- ASP.NET 5 RC1 升级 ASP.NET Core 1.0 RC2 记录
升级文档: Migrating from DNX to .NET Core Migrating from ASP.NET 5 RC1 to ASP.NET Core 1.0 RC2 Migrating ...
随机推荐
- Torch7学习笔记(一)CmdLine
该类主要为了提供一种方便解析参数的框架,对于每个实验尤其是神经网络中要调参数上.同时还可以把输出重定向到log文件中. 一般用法: cmd = torch.CmdLine() cmd:text() c ...
- browsersync实现网页实时刷新(修改LESS,JS,HTML时)
var gulp = require("gulp"), less = require("gulp-less"), browserSync = require(& ...
- Maven打包 报 Unable to locate the Javac Compiler in: C:\Program Files\Java\jre1.8.0_73\..\lib\tools.jar
无法找到javac 编译环境 右键项目 --> properties -->Java Build Path -->选中JRE 点击右侧 Edit 编辑 --> 把你设置的JRE ...
- ubuntu 下emacs 配置
(set-language-environment 'Chinese-GB) (set-keyboard-coding-system 'utf-8) (set-clipboard-coding-sys ...
- ratina 视网膜屏幕解决方案大全
第三方教程 http://www.tuicool.com/articles/JBreIn 知乎 https://www.zhihu.com/question/21653056 强烈推荐!!!最牛逼最专 ...
- properties文件使用{0}...
例如properties文件的配置 weixin.token.url=https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credent ...
- SQL Server全时区转换
SQL Server全时区转换 假如你的应用程序是跨国(例如跨国银行交易)使用的话,那么数据库的一些国际化特性支持可以说是非常重要 其中最常见的就是各国时区上的差异,由于SQL Server getd ...
- 基于Redis的开源分布式服务Codis
Redis在豌豆荚的使用历程--单实例==>多实例,业务代码中做sharding==>单个Twemproxy==>多个Twemproxy==>Codis,豌豆荚自己开发的分布式 ...
- 常用SQL[ORACLE]
1.常用系统函数 2.常用sql语句 3.一些定义和关键字 4.需要注意点 1.常用系统函数 ↑ --decode decode(column,if_value,value,elseif_ ...
- Expert 诊断优化系列------------------给TempDB 降温
前面文章针对CPU.内存.磁盘.语句.等待讲述了SQL SERVER的一些基本的问题诊断与调优方式.为了方便阅读给出导读文章链接方便阅读: SQL SERVER全面优化-------Expert fo ...