Visual Studio 2013 で HttpClient を使用して Web API の単体テスト / 統合テストを行う 質問する

Visual Studio 2013 で HttpClient を使用して Web API の単体テスト / 統合テストを行う 質問する

Visual Studio 2013 で API コントローラーをテストするのに苦労しています。私のソリューションには、Web API プロジェクトとテスト プロジェクトがあります。テスト プロジェクトには、次のような単体テストがあります。

[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;
    }
}

404が何度も表示されます。Visual Studio の 1 つのインスタンス (IIS Express) で API を実行し、別のインスタンスでこのユニット テストをデバッグしようとしました。しかし、うまくいきませんでした。この URL をブラウザーに入力できることを確認しました (1 つの Visual Studio がデバッグ中の場合)。JSON 応答が表示されます。しかし、ユニット テストでこれを動作させる方法がわかりません。HttpClientオンラインで例を見つけようとしましたが、見つからないようです。誰か助けてくれませんか?

更新1:ルートを追加しようとしましたが、何も起こりませんでした。

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]

これが私のAPIコントローラーです

[HttpGet]
[Route("api/product/hello/")]
public IHttpActionResult Hello()
{
     return Ok();
}

更新解像度:HttpClientオブジェクトなしで新規に起動すると、動作させることができましたHttpServer。ただし、VS のインスタンスを 2 つ実行する必要があります。1 つは API コードを実行し、もう 1 つはユニット テストを実行します。

ここに作業方法があります。

[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);
    }
}

HttpServerHttpConfigurationが に渡されると動作しない理由を知っている人はいますかHttpClient? これを使用する例をたくさん見てきました。

ベストアンサー1

以下の記事を参考にしてできました...

インメモリホスティングによる ASP.NET Web API 統合テスト

HttpServerとにHttpConfiguration渡された を操作しますHttpClient。次の例では、ApiController属性ルーティングを使用する単純な を作成しました。 を設定してHttpConfiguration属性ルートをマップし、それを新しい に渡しましたHttpServerHttpClientは、設定されたサーバーを使用して、テスト サーバーへの統合テスト呼び出しを行うことができます。

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();
        }
    }
}

コントローラーの統合テストを行うために、VS の別のインスタンスを実行する必要はありませんでした。

次の簡易版のテストも有効でした

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);
    }
}

あなたの場合、Web API 設定に合わせてサーバーを適切に構成していることを確認する必要があります。つまり、オブジェクトに API ルートを登録する必要がありますHttpConfiguration

var config = new HttpConfiguration();
//configure web api
WebApiConfig.Register(config);
//...other code removed for brevity

おすすめ記事