单元测试场景中带有asp.net WebApi的HttpClient

Posted

技术标签:

【中文标题】单元测试场景中带有asp.net WebApi的HttpClient【英文标题】:HttpClient with asp.net WebApi in unit testing scenario 【发布时间】:2012-05-04 09:26:40 【问题描述】:

我有一个集成测试,我想用它作为测试我的 WebAPI 控制器的基础。

最初我认为我必须在自托管模式下设置 WebAPI 并通过本地 Http 执行端到端测试。

但是我后来通过查看 WebApiContrib 项目中的测试意识到,可以设置一个带有 HttpServer 设置的 HttpClient 以及到 WebAPI 控制器的正确服务路由。我似乎可以对控制器进行单元测试,而无需在自托管模式下设置 WebApi。我可以在客户端的请求中输入任何域名,HttpClient 似乎自动神奇地绑定到正确的控制器。

这里是否发生了任何 Http 传输,使用一些本地进程间通信或纯粹“看到”服务器位于同一个应用程序域中并因此使用反射? 发生这种情况的幕后原因是什么?

代码:

[Test]
public void Test_WebApi_Controller()

    Assembly.Load("myproj.Web");

    var prodServiceMock = new Mock<IProductService>();
    ObjectFactory.Initialize(x => x.For<IProductService>().Use(prodServiceMock.Object));                      

    var config = new HttpConfiguration();
    config.Routes.MapHttpRoute("default", "webapi/controller/id", new  id = RouteParameter.Optional );
    config.ServiceResolver.SetResolver(new WebApiDependencyResolver());

    var server = new HttpServer(config);
    var client = new HttpClient(server);

    var response = client.GetAsync("http://anything.com/webapi/product").Result;


【问题讨论】:

【参考方案1】:

HttpClient 具有可插拔的管道模型。通常,当您新建一个 HttpClient 时,您会获得一个 HttpClientHandler 实例作为默认请求处理器。 HttpClientHandler 是实际执行 HttpWebRequest 的那个。 HttpClientHandler 派生自 HttpMessageHandler。

毫无疑问,HttpServer 也派生自 HttpMessageHandler。所以在这个例子中,HttpServer 被传递给 HttpClient 实例以提供它的请求处理。通过将 HttpMessageHandler 传递给 HttpClient 的构造函数,您是在告诉 HttpClient 使用提供的处理程序而不是默认的处理程序。如果您查看 System.Net.Http.WebRequest 中的 WebRequestHandler,您会发现这是从 HttpClientHandler 派生的,并添加了一些特定于 Windows 桌面操作系统的额外功能。

这意味着当您向 HTTPClient 发出请求时,它会直接传递给 HttpServer 消息处理程序,然后像通常在服务器上一样进行处理。

【讨论】:

那么它是如何知道如何直接调用处理程序的呢? HttpServer不也是用来做网络连接的吗? @jaffa HttpClient 将所有请求发送到已提供给它的 HttpMessageHandler。 HttpServer 位于处理所有网络内容的主机上。 IIS、WCF Self Host 或其他一些 Owin 主机。

以上是关于单元测试场景中带有asp.net WebApi的HttpClient的主要内容,如果未能解决你的问题,请参考以下文章

Asp.net WebApi + EF 单元测试架构 DbContext一站到底

ASP.NET Web API 中带有可选参数的属性路由

由于 HttpStatusCode.TemporaryRedirect 导致 VSTS 管道中的 ASP.NET Core 单元测试失败

ASP.NET Web API - HttpClient.PostAsync 本地 API 不会进入代码

.NET异步性能测试(ASP.NET MVC WebAPI异步方法)

ASP.NET Core中为指定类添加WebApi服务功能