ASP.NET 单元测试不映射路由
ASP.NET Unit testing doesn't map routes
我有一个 Web API 项目,我想用单元测试来测试它。
在测试中 class 我创建了一个 HttpClient
应该将 HTTP 调用直接重定向到我的控制器:
public static HttpClient GetInMemoryServerClient(HttpConfiguration serverConfig)
{
var config = serverConfig ?? new HttpConfiguration();
MyService.WebApiConfig.Register(config, isTest: true);
var server = new HttpServer();
server.Configuration.Services.Replace(typeof(IHttpActionInvoker), server.Configuration.Services.GetActionInvoker());
return new HttpClient(server) { BaseAddress = new Uri("http://fakehost:9999/") };
}
在服务项目中,我有一个调用 config.MapHttpAttributeRoutes()
的 class,它在产品中有效,但在测试调用时无效:
public class WebApiConfig{
//...
public static void Register(HttpConfiguration config) // this is called in Global.asax.cs
{
Register(config, false);
}
public static Register(HttpConfiguration config, bool isTest){
//... various config and dependency injection setup here
config.MapHttpAttributeRoutes();
}
}
我的控制器使用属性路由:
[RoutePrefix("api/groups/{groupId}/sets/{setId:minlength(1)}/items")]
public class ItemsController : BaseController
{
[Route("{itemId:minlength(1)}")]
[HttpGet]
public async Task<API.Item> Get(string groupId, string setId, string itemId)
{...}
}
当我使用 HttpClient
拨打电话时,我收到
{"Message":"No HTTP resource was found that matches the request URI
'http://fakehost:9999/api/groups/abc/sets/xyz/items/item123'
."}
并使用我看到的调试器检查 httpClient
httpClient.handler.Configuration.Routes.Count == 0
,因此映射路由属性不起作用
问:设置假 HttpClient
以便我的单元测试可以使用它来调用控制器的正确方法是什么?
HttpConfiguration config
未分配给服务器,因此未应用设置。该方法将映射应用于配置,但在初始化时未将配置分配给服务器。
public static HttpClient GetInMemoryServerClient(HttpConfiguration serverConfig = null) {
var config = serverConfig ?? new HttpConfiguration();
MyService.WebApiConfig.Register(config, isTest: true);
var server = new HttpServer(config); //<-- pass config to server
var client = new HttpClient(server);
//Server defaults to localhost so setting client to localhost as well
client.BaseAddress = new Uri("http://localhost");
return client;
}
在测试中客户端可以调用
using(var client = GetInMemoryServerClient()) {
var url = "api/groups/abc/sets/xyz/items/item123";
var response = await client.GetAsync(url);
//...do something with response
}
我有一个 Web API 项目,我想用单元测试来测试它。
在测试中 class 我创建了一个 HttpClient
应该将 HTTP 调用直接重定向到我的控制器:
public static HttpClient GetInMemoryServerClient(HttpConfiguration serverConfig)
{
var config = serverConfig ?? new HttpConfiguration();
MyService.WebApiConfig.Register(config, isTest: true);
var server = new HttpServer();
server.Configuration.Services.Replace(typeof(IHttpActionInvoker), server.Configuration.Services.GetActionInvoker());
return new HttpClient(server) { BaseAddress = new Uri("http://fakehost:9999/") };
}
在服务项目中,我有一个调用 config.MapHttpAttributeRoutes()
的 class,它在产品中有效,但在测试调用时无效:
public class WebApiConfig{
//...
public static void Register(HttpConfiguration config) // this is called in Global.asax.cs
{
Register(config, false);
}
public static Register(HttpConfiguration config, bool isTest){
//... various config and dependency injection setup here
config.MapHttpAttributeRoutes();
}
}
我的控制器使用属性路由:
[RoutePrefix("api/groups/{groupId}/sets/{setId:minlength(1)}/items")]
public class ItemsController : BaseController
{
[Route("{itemId:minlength(1)}")]
[HttpGet]
public async Task<API.Item> Get(string groupId, string setId, string itemId)
{...}
}
当我使用 HttpClient
拨打电话时,我收到
{"Message":"No HTTP resource was found that matches the request URI
'http://fakehost:9999/api/groups/abc/sets/xyz/items/item123'
."}
并使用我看到的调试器检查 httpClient
httpClient.handler.Configuration.Routes.Count == 0
,因此映射路由属性不起作用
问:设置假 HttpClient
以便我的单元测试可以使用它来调用控制器的正确方法是什么?
HttpConfiguration config
未分配给服务器,因此未应用设置。该方法将映射应用于配置,但在初始化时未将配置分配给服务器。
public static HttpClient GetInMemoryServerClient(HttpConfiguration serverConfig = null) {
var config = serverConfig ?? new HttpConfiguration();
MyService.WebApiConfig.Register(config, isTest: true);
var server = new HttpServer(config); //<-- pass config to server
var client = new HttpClient(server);
//Server defaults to localhost so setting client to localhost as well
client.BaseAddress = new Uri("http://localhost");
return client;
}
在测试中客户端可以调用
using(var client = GetInMemoryServerClient()) {
var url = "api/groups/abc/sets/xyz/items/item123";
var response = await client.GetAsync(url);
//...do something with response
}