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 
}