4

HttpRequestMessageインスタンスを渡し、インスタンスを受け取ることによってクラス ライブラリを呼び出す単体テストがありHttpResponseMessagesます。この点では、WebApi のテストと非常によく似ていますApiController

私がテストしているコードは に Cookie を追加しHttpResponseMessage、その後の着信HttpRequestMessage呼び出しでそれらの Cookie が表示されることを期待しています。これは、ブラウザー (またはHttpWebRequest) の動作です。

HttpClientHandlerリクエストは実際にはネットワーク上で行われていないため、使用していませんが、HttpMessageHandler初期化したモックアップを使用して製品に渡されHttpClientます。したがって、での Cookie 処理にHttpClientHandlerはアクセスできません。必要な Cookie の動作を取得するには、 の Cookie を手動で解析してHttpResponseMessageから、手動で にシリアル化する必要があるようHttpRequestMessageです。これは、CookieContainer が Cookie を適切なリクエストに正しく適用するためのロジックも完全に省略しています。

もっと簡単な方法はありますか?

4

1 に答える 1

6

私は自分のDelegatingHandlerためにクッキーを管理するものを書きました。およびCookieContainerで簡単に使用できるように、いくつかの拡張メソッドも作成しました。HttpRequestMessageHttpResponseMessage

internal class DangerouslySimpleCookieContainer : DelegatingHandler {
    internal DangerouslySimpleCookieContainer(CookieContainer cookieContainer = null) {
        this.Container = cookieContainer ?? new CookieContainer();
    }

    internal DangerouslySimpleCookieContainer(HttpMessageHandler innerHandler, CookieContainer cookieContainer = null)
        : base(innerHandler) {
        this.Container = cookieContainer ?? new CookieContainer();
    }

    public CookieContainer Container { get; set; }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
        this.Container.ApplyCookies(request);
        var response = await base.SendAsync(request, cancellationToken);
        this.Container.SetCookies(response);
        return response;
    }
}

internal static class CookieContainerExtensions {
    internal static void SetCookies(this CookieContainer container, HttpResponseMessage response, Uri requestUri = null) {
        Requires.NotNull(container, "container");
        Requires.NotNull(response, "response");

        IEnumerable<string> cookieHeaders;
        if (response.Headers.TryGetValues("Set-Cookie", out cookieHeaders)) {
            foreach (string cookie in cookieHeaders) {
                container.SetCookies(requestUri ?? response.RequestMessage.RequestUri, cookie);
            }
        }
    }

    internal static void ApplyCookies(this CookieContainer container, HttpRequestMessage request) {
        Requires.NotNull(container, "container");
        Requires.NotNull(request, "request");

        string cookieHeader = container.GetCookieHeader(request.RequestUri);
        if (!string.IsNullOrEmpty(cookieHeader)) {
            request.Headers.TryAddWithoutValidation("Cookie", cookieHeader);
        }
    }
}
于 2013-03-23T16:01:50.293 に答える