2012-05-04 40 views
9

我有一个集成测试,我想用它作为测试WebAPI控制器的基础。在单元测试场景中使用asp.net WebApi的HttpClient

最初我以为我必须在自主模式下设置WebAPI,并在本地Http上执行端到端测试。

但是,后来我通过查看WebApiContrib项目中的测试意识到,可以使用正确的服务路由到WebAPI控制器来设置具有HttpServer设置的HttpClient。我似乎可以单元测试控制器,而无需在自主模式下设置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; 

} 

回答

9

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

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

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

+0

那么它如何知道如何直接调用处理程序呢? HttpServer是否也用于网络连接? – jaffa

+0

@jaffa HttpClient将所有请求发送到已提供给它的HttpMessageHandler。 HttpServer位于处理所有网络事物的主机上。无论是IIS,WCF自主主机,还是其他一些Owin主机。 –