今天在开发一个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单元测试的更多相关文章

  1. 用Owin Host实现脱离IIS跑Web API单元测试

    开发笔记:用Owin Host实现脱离IIS跑Web API单元测试   今天在开发一个ASP.NET Web API项目写单元测试时,实在无法忍受之前的笨方法,决定改过自新. 之前Web API的单 ...

  2. 使用Nancy.Host实现脱离iis的Web应用

    本篇将介绍如何使用Nancy.Host实现脱离iis的Web应用,在开源任务管理平台TaskManagerV2.0代码里面已经使用了Nancy.Host实现自宿主的Web应用.学习Nancy之前最好了 ...

  3. 以Self Host的方式来寄宿Web API

    Common类及实体定义.Web API的定义请参见我的上一篇文章:以Web Host的方式来寄宿Web API. 一.以Self Host寄宿需要新建一个Console控制台项目(SelfHost) ...

  4. PCB 脱离IIS的Web应用

    在用.net Web编程中,我们写好的Web应用首选会挂在IIS上面,因为它足稳定并且功能齐全,但这不是我们唯一的选择,微软给我们提供了Owin组件,Web应该的宿主可以不再是IIS了,有了Owin后 ...

  5. Owin asp.net 脱离 IIS

    http://www.cnblogs.com/jesse2013/p/owin-webserver.html

  6. 以Web Host的方式来寄宿Web API

    一.新建一个Common的类库项目并新建一个测试用的Contact实体类 namespace Common { public class Contact { public string Id { ge ...

  7. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

  8. [转] 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/ ...

  9. 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 ...

随机推荐

  1. rabbitmq安装

    1.从源码安装最新的otperlang17,版本(otp_src_17.1.tar.gz): ./configure make make install 2.有可能要安装    和simplebean ...

  2. linux ssh config

    Host code.engineering.redhat.com    HostName code.engineering.redhat.com    Port 29418    User jiall ...

  3. Oracle第三方ado.net数据提供程序

    原文地址:http://www.infoq.com/cn/news/2009/06/oracleclient_deprecated 这项决定有部分原因是基于目前Oracle的第三方ADO.NET数据提 ...

  4. Linux内核--网络栈实现分析(九)--传输层之UDP协议(下)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7549340 更多请查看专栏,地 ...

  5. HTML5-属性

    点击图片打开详细介绍页面

  6. 黑马程序员+SQL基础(上)

    黑马程序员+SQL基础 ---------------<a href="http://edu.csdn.net"target="blank">ASP ...

  7. Ubuntu 初始化Root账户密码

    昨晚新装的Ubuntu12(电脑太烂了),每次都记不住初始化root密码的命令,既然决定开始写自己的园子了,那就在自己的园子里面记一下,方便自己稳固之心 好了,不废话了了 draenei@ubuntu ...

  8. Web 架构师的能力(转)

    文/刘如鸿 最近和几个朋友在谈到时下流行的Web 2.0,也提到了其中最重要的角色——架构师.多方各有争执,不外乎是因为背景和视角的缘故,包括架构一词,本身就从建筑学借鉴而来,至于架构师,则可以 简单 ...

  9. windbg 基础命令实战 - 简单程序破解

    以前玩游戏遇到一些实在过不去的管卡,经常会找一些游戏修改软件来修改游戏,让自己变得无比强大,将boss一路砍瓜切菜过足游戏瘾.其实游戏修改软件的功能大多都比较简单,我们可以通过windbg的一些简单命 ...

  10. [备忘]删除SQL Server中无登录名的用户

    这个问题通常会在还原虚拟主机的备份SQL文件后发生,原先在虚拟主机上的用户会被还原到本地,但是本地没有权限对其进行操作. SELECT N'ALTER AUTHORIZATION ON SCHEMA: ...