开发笔记:用Owin Host实现脱离IIS跑Web API单元测试
今天在开发一个ASP.NET Web API项目写单元测试时,实在无法忍受之前的笨方法,决定改过自新。
之前Web API的单元测试需要进行以下的操作:
初始配置:
1)在IIS中创建一个站点指定Web API项目
2)在hosts加上该站点的IP地址解析
每次修改代码:
3)修改代码之后按F6编译
4)用TestDriven.Net运行单元测试
一看就知道这个方法好土、好笨、好受罪。理想的方式应该是:无需任何初始配置,修改代码之后无需按F6编译,直接运行单元测试,一步完成操作。
今天在受不了旧方式的折磨、经不起理想方式的诱惑的情况下,下定决心要解决这个问题,最终通过Owin Host实现了,通过这篇博文分享一下。
用Owin Host实现的思路很简单,就是在单元测试中以Owin Host运行ASP.NET Web API站点,然后单元测试代码直接请求这个Owin Host站点进行测试。
我们的Web API项目是基于ASP.NET 4.5 + ASP.NET Web API 5.2.3开发的,没有OWIN相关的代码,所以先要在Web API项目中添加一些代码 ,以让Owin Host能够加载之。
首先nuget安装Owin包包(IAppBuilder在此包中):
PM> Install-Package Owin
然后添加Startup.cs:
public class Startup
{
public void Configuartion(IAppBuilder app)
{
}
}
接着nuget安装Microsoft.AspNet.WebApi.Owin包包(app.UseWebApi扩展方法在此包中)
PM> Install-Package Microsoft.AspNet.WebApi.Owin
在Startup.Configuratrion方法中添加代码,调用WebApiConfig.Register方法(这个是之前已经实现的,路由配置就在其中)配置HttpConfiguration,然后将之注册到OWIN的管线中。
public class Startup
{
public void Configuration(IAppBuilder app)
{
var configuraton = new HttpConfiguration();
WebApiConfig.Register(configuraton);
app.UseWebApi(configuraton);
}
}
Web API项目只需这样简单改造一下,就可以支持Owin Host,无任何副作用,不影响用IIS部署站点。
单元测试代码的改造也很简单,只需在跑测试之前用Microsoft.Owin.Hosting中的WebApp.Start()方法加载Web API站点。
首先nuget安装Owin Host的包包:
PM> Install-Package Microsoft.Owin.Hosting
PM> Install-Package Microsoft.Owin.Host.HttpListener
接着在测试类的构造函数中用WebApp.Start()启动Web API站点:
public class CommentsWebApiTest : IDisposable
{
private const string HOST_ADDRESS = "http://localhost:8001";
private IDisposable _webApp;
public CommentsWebApiTest()
{
_webApp = WebApp.Start<Startup>(HOST_ADDRESS);
Console.WriteLine("Web API started!");
} public void Dispose()
{
_webApp.Dispose();
}
}
然后就可以脱离IIS无比轻松地进行Web API的单元测试了。
下面来实际体验一下:
1)在Web API项目中实现一个ApiController
public class CommentsController : ApiController
{
[Route("blogposts/{postId}/comments")]
public async Task<IHttpActionResult> Get(int postId)
{
var comments = new Comment[] { new Comment {
PostId = postId,
Body = "Coding changes the world1" } };
return Ok<Comment[]>(comments);
}
}
2)编写基于Owin Host跑Web API站点的单元测试代码
public class CommentsWebApiTest : IDisposable
{
private const string HOST_ADDRESS = "http://localhost:8001";
private IDisposable _webApp;
private HttpClient _httClient; public CommentsWebApiTest()
{
_webApp = WebApp.Start<Startup>(HOST_ADDRESS);
Console.WriteLine("Web API started!");
_httClient = new HttpClient();
_httClient.BaseAddress = new Uri(HOST_ADDRESS);
Console.WriteLine("HttpClient started!");
} public void Dispose()
{
_httClient.Dispose();
_webApp.Dispose();
} [Fact]
public async Task GetComments()
{
var postId = ;
var response = await _httClient.GetAsync($"/blogposts/{postId}/comments");
if(response.StatusCode != HttpStatusCode.OK)
{
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var comments = await response.Content.ReadAsAsync<Comment[]>();
Assert.NotEmpty(comments);
Assert.Equal(postId, comments[].PostId);
Assert.Equal("Coding changes the world", comments[].Body);
}
}
注:除了nuget安装Microsoft.Owin.Hosting与Microsoft.Owin.Host.HttpListener包包,还要安装Microsoft.AspNet.WebApi.Client包包(ReadAsAsync<Comment[]>在此包中)。
3)运行单元测试:在单元测试方法中点击鼠标右键并点击Run Test(s)(用的是TestDriven.Net,会在单元测试前自动进行编译)

4)查看单元测试结果,验证测试Web API的理想方式是否实现:
Output from WebApiTests.CommentsWebApiTest.GetComments:
Web API started!
HttpClient started! 1 passed, 0 failed, 0 skipped, took 4.91 seconds (xUnit.net 1.9.2 build 1705).
测试通过!理想方式实现!
这次经历再次证明了,当有一个问题影响你写代码的乐趣时,一定要尽早下定决心解决它,否则它浪费的时间很可能是解决这个问题所需时间的n倍,而且很多时候解决一个问题的难易程度取决于你下的决心有多大。
【更新】
需要注意一个地方,在单元测试中以owin host运行web api站点时,配置信息(比如数据库连接字符串)是从单元测试项目的app.config中读取,而不是从web api项目的web.config中读取,所以要将web.config中的相关配置复制到app.config中。
【参考资料】
ASP.NET Web API Integration Testing with One Line of Code
开发笔记:用Owin Host实现脱离IIS跑Web API单元测试的更多相关文章
- 用Owin Host实现脱离IIS跑Web API单元测试
开发笔记:用Owin Host实现脱离IIS跑Web API单元测试 今天在开发一个ASP.NET Web API项目写单元测试时,实在无法忍受之前的笨方法,决定改过自新. 之前Web API的单 ...
- 使用Nancy.Host实现脱离iis的Web应用
本篇将介绍如何使用Nancy.Host实现脱离iis的Web应用,在开源任务管理平台TaskManagerV2.0代码里面已经使用了Nancy.Host实现自宿主的Web应用.学习Nancy之前最好了 ...
- 以Self Host的方式来寄宿Web API
Common类及实体定义.Web API的定义请参见我的上一篇文章:以Web Host的方式来寄宿Web API. 一.以Self Host寄宿需要新建一个Console控制台项目(SelfHost) ...
- PCB 脱离IIS的Web应用
在用.net Web编程中,我们写好的Web应用首选会挂在IIS上面,因为它足稳定并且功能齐全,但这不是我们唯一的选择,微软给我们提供了Owin组件,Web应该的宿主可以不再是IIS了,有了Owin后 ...
- Owin asp.net 脱离 IIS
http://www.cnblogs.com/jesse2013/p/owin-webserver.html
- 以Web Host的方式来寄宿Web API
一.新建一个Common的类库项目并新建一个测试用的Contact实体类 namespace Common { public class Contact { public string Id { ge ...
- [置顶] Android开发笔记(成长轨迹)
分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...
- [转] JSON Web Token in ASP.NET Web API 2 using Owin
本文转自:http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/ ...
- JSON Web Token in ASP.NET Web API 2 using Owin
In the previous post Decouple OWIN Authorization Server from Resource Server we saw how we can separ ...
随机推荐
- MSVCRTD.lib(mfc.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainC (转)
一.问题描述 我所使用的编程环境:VS2010 出现的问题如下: MSVCRTD.lib(mfc.obj) : error LNK2019: 无法解析的外部符号_WinMain@16,该符号在函数 _ ...
- mysql命令化操作实用小技巧
★1.问:如果我的mysql数据库服务器程序在D:\program files\phpstudy\mysql,里,那么我该怎么在cmd命令状态下使用它? 进入cmd状态后,系统默认在当前用户 ...
- rlwrap-0.37.tar.gz实现sqlplus上下翻页
1.上传rlwrap-0.37.tar.gz到linux 2.解压rlwrap-0.37.tar.gz [root@node1 mnt]# tar zxvf rlwrap-0.37.tar.gz [r ...
- 备库Seconds_Behind_Master的计算
背景 在mysql主备环境下,主备同步过程如下,主库更新产生binlog, 备库io线程拉取主库binlog生成relay log.备库sql线程执行relay log从而保持和主库同步. 理论上主库 ...
- Web Essentials之HTML和CSS操作技巧
返回Web Essentials功能目录 一些Javascript功能也可以用于TypeScript. 本篇目录 功能 ZenCoding LESS 功能 最小化HTML文件 选中要最小化的.html ...
- TypeError: 'bases' is null or not an object。IE8 bug 腐朽的对象
使用Webapp Builder时候发现,在IE8上很奇怪的一个现象:在ajax回调函数中引用一个闭包作用域链中的对象作为某一个Dijit的实例化参数时有问题:bases is null or not ...
- JavaScript思维导图—运算符
JavaScript思维导图-来自@王子墨http://julying.com/blog/the-features-of-javascript-language-summary-maps/
- Oracle存在修改,不存在插入记录
接触编程以来,在数据存储方面一直用的MS SQL.Oracle这名字对我来说是如此的熟悉,但是对其内容却很陌生,最近公司的一个项目用起了Oracle,所以也开始高调的用起了Oracle.在没有接触Or ...
- 赴美工作常识(Part 6 - 绿卡排队)
上一篇<赴美工作常识(Part 5 - 绿卡优先级)>解释完排队的优先级是怎么确定的,以及 PERM 和 I–140 表的意义,接下来就要解释一下队具体是怎么排的以及排到之后的 I–485 ...
- mysqlnd cannot connect to MySQL 4.1+
phpMyAdmin - error #2000 - mysqlnd cannot connect to MySQL 4.1+ using the old insecure authenticatio ...