Es fällt mir schwer, meinen API-Controller mit Visual Studio 2013 zu testen. Meine eine Lösung verfügt über ein Web-API-Projekt und ein Testprojekt. In meinem Testprojekt habe ich einen Unit Test mit:
[TestMethod]
public void GetProduct()
{
HttpConfiguration config = new HttpConfiguration();
HttpServer _server = new HttpServer(config);
var client = new HttpClient(_server);
var request = new HttpRequestMessage
{
RequestUri = new Uri("http://localhost:50892/api/product/hello"),
Method = HttpMethod.Get
};
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var response = client.SendAsync(request).Result)
{
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var test = response.Content.ReadAsAsync<CollectionListDTO>().Result;
}
}
Ich bekomme immer eine 404. Ich habe versucht, meine API mit einer Instanz von Visual Studio (IIS Express) auszuführen und diesen Komponententest in einer anderen Instanz zu debuggen. Aber kein glück Ich habe überprüft, ob ich diese URL in einem Browser ablegen kann (wenn in einem Visual Studio ein Debugging ausgeführt wird), und es wird meine JSON-Antwort angezeigt. Aber ich kann nicht herausfinden, wie ich es mit meinem Unit-Test und HttpClient
zum Laufen bringen kann. Ich habe versucht, online Beispiele zu finden, kann aber scheinbar keine finden. Kann jemand helfen?
PDATE 1: Ich habe versucht, eine Route hinzuzufügen, aber es ist nichts passiert.
HttpConfiguration config = new HttpConfiguration();
// Added this line
config.Routes.MapHttpRoute(name: "Default", routeTemplate: "api/product/hello/");
HttpServer _server = new HttpServer(config);
var client = new HttpClient(_server);
[...rest of code is the same]
Hier ist mein API-Controller
[HttpGet]
[Route("api/product/hello/")]
public IHttpActionResult Hello()
{
return Ok();
}
PDATE Resolution: Ich konnte es zum Laufen bringen, wenn ich HttpClient
ohne HttpServer
Objekt neu einrichte. Ich müsste immer noch zwei Instanzen von VS ausführen. Ich führe meinen API-Code und einen anderen aus, um den Komponententest auszuführen.
Hier ist eine Arbeitsmethode.
[TestMethod]
public void Works()
{
var client = new HttpClient(); // no HttpServer
var request = new HttpRequestMessage
{
RequestUri = new Uri("http://localhost:50892/api/product/hello"),
Method = HttpMethod.Get
};
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var response = client.SendAsync(request).Result)
{
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}
Weiß jemand, warum es nicht mit einem HttpServer
und einem HttpConfiguration
funktioniert, die an HttpClient
übergeben wurden? Ich habe viele Beispiele gesehen, die dies verwenden.
Unter Bezugnahme auf den folgenden Artikel konnte ich ...
ASP.NET-Web-API-Integrationstest mit In-Memory-Hosting
indem Sie mit einem HttpServer
und einem HttpConfiguration
arbeiten, die an HttpClient
übergeben wurden. Im folgenden Beispiel habe ich ein einfaches ApiController
erstellt, das Attributrouting verwendet. Ich habe HttpConfiguration
so konfiguriert, dass Attributrouten zugeordnet werden, und habe es dann an das neue HttpServer
übergeben. Das HttpClient
kann dann den konfigurierten Server verwenden, um Integrationstestaufrufe an den Testserver zu tätigen.
public partial class MiscUnitTests {
[TestClass]
public class HttpClientIntegrationTests : MiscUnitTests {
[TestMethod]
public async Task HttpClient_Should_Get_OKStatus_From_Products_Using_InMemory_Hosting() {
var config = new HttpConfiguration();
//configure web api
config.MapHttpAttributeRoutes();
using (var server = new HttpServer(config)) {
var client = new HttpClient(server);
string url = "http://localhost/api/product/hello/";
var request = new HttpRequestMessage {
RequestUri = new Uri(url),
Method = HttpMethod.Get
};
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var response = await client.SendAsync(request)) {
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}
}
}
public class ProductController : ApiController {
[HttpGet]
[Route("api/product/hello/")]
public IHttpActionResult Hello() {
return Ok();
}
}
}
Es war nicht erforderlich, dass eine andere VS-Instanz ausgeführt wurde, um den Controller zu integrieren.
Die folgende vereinfachte Version des Tests hat ebenfalls funktioniert
var config = new HttpConfiguration();
//configure web api
config.MapHttpAttributeRoutes();
using (var server = new HttpServer(config)) {
var client = new HttpClient(server);
string url = "http://localhost/api/product/hello/";
using (var response = await client.GetAsync(url)) {
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}
In Ihrem Fall müssen Sie sicherstellen, dass Sie den Server richtig für Ihre Web-API-Einrichtung konfigurieren. Dies würde bedeuten, dass Sie Ihre API-Routen mit dem Objekt HttpConfiguration
registrieren müssen.
var config = new HttpConfiguration();
//configure web api
WebApiConfig.Register(config);
//...other code removed for brevity