2

DelegateHandler の実装を単体テストしようとしています。私の単純化された実装:

public class FooHandler
    : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Vegard"), new[] { "A", "B" });

        return await base.SendAsync(request, cancellationToken);
    }
}

これを単体テストしようとすると、次のようにします。

public class TestHandler : DelegatingHandler
{
    private readonly Func<HttpRequestMessage,
        CancellationToken, Task<HttpResponseMessage>> _handlerFunc;
    public TestHandler()
    {
        _handlerFunc = (r, c) => Return(HttpStatusCode.OK);
    }

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return _handlerFunc(request, cancellationToken);
    }

    public static Task<HttpResponseMessage> Return(HttpStatusCode status)
    {
        return Task.Factory.StartNew(
            () => new HttpResponseMessage(status));
    }
}

[TestMethod]
public async Task SendAsync_CorrectTokens_IsAuthorized()
{
    var message = new HttpRequestMessage(HttpMethod.Get, "http://www.test.com");

    var handler = new AuthorizationHeaderHandler
        {
            InnerHandler = new TestHandler()
        };

    var invoker = new HttpMessageInvoker(handler);
    var result = await invoker.SendAsync(message, new CancellationToken());

    Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
    Assert.IsTrue(Thread.CurrentPrincipal.Identity.IsAuthenticated); // fails
    Assert.AreEqual("Vegard", Thread.CurrentPrincipal.Identity.Name); // fails
}

私の推測では、これは別のスレッドでHttpMessageInvoker実行されるために発生します。DelegateHandlerこれらを強制的に同じスレッドに配置できますか?

4

2 に答える 2

2

実際に実行しているのは、await の動作です。Await は、await を終了するときに、await に入ったときのプリンシパルをリセットします。したがって、await invoker.SendAsync を呼び出すときに現在のプリンシパルがないため、その呼び出しを待機した後は現在のプリンシパルはありません。

ただし、テスト ハンドラーは正しいプリンシパルを参照する必要があります。できることは、テスト ハンドラーに現在のプリンシパルをその SendAsync 実装に格納させ、それをパブリック プロパティとして公開してから、テスト ハンドラーが想定されているプリンシパルを見たことをテストにアサートさせることです。それは問題なく動作するはずであり、それはあなたが気にする動作でなければなりません.

于 2013-06-10T13:39:13.717 に答える