2

我有一个Web API项目,我想用单元测试来测试。ASP.NET单元测试不映射路线

在测试类我创建了应该重定向HTTP一个HttpClient直接调用到我的控制器:

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(),其正式版,但不工作当被测试,称为:

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拨打电话我得到

{ “消息”: “没有HTTP资源发现,请求URI 'http://fakehost:9999/api/groups/abc/sets/xyz/items/item123'相匹配。”}

和检查httpClient与调试我看到httpClient.handler.Configuration.Routes.Count == 0,所以映射路由属性没有工作

问:什么是建立假冒正确的方法所以我的单元测试可以用它来调用控制器?

+0

呼叫你有没有在这里拍摄一看? https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client – trevster344

+1

服务器在测试中默认使用'localhost' 。所以你的默认地址不起作用。此外,这将被归类为集成测试。不是单元测试。 – Nkosi

+0

看看我在这个答案中是如何做类似的。 http://stackoverflow.com/a/40423984/5233410 – Nkosi

回答

1

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 
}