单元测试DelegatingHandler

时间:2015-07-27 10:27:38

标签: c# unit-testing asp.net-web-api delegatinghandler

如何对自定义DelegatingHandler进行单元测试?我有以下内容,但它抱怨innerHandler未设置。

var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://foo.com");
var handler = new FooHandler()
{
    InnerHandler = new FooHandler() 
};

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

Assert.That(result.Headers.GetValues("some-header").First(), Is.Not.Empty, "");

3 个答案:

答案 0 :(得分:10)

您可以使用假/假处理程序(InnerHandler)设置您正在测试的DelegatingHandler的FooHandler属性(TestHandler),如that linked post中所示评价。

public class TestHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return Task.Factory.StartNew(() => new HttpResponseMessage(HttpStatusCode.OK), cancellationToken);
    }
}

 // in your test class method
    var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://foo.com");
    var handler = new FooHandler()
    {
        InnerHandler = new TestHandler()  // <-- change to use this

    };

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

    Assert.That(result.Headers.GetValues("some-header").First(), Is.Not.Empty, "");

与该帖子不同,这应该是您需要设置的最小值才能让您的测试运行。

答案 1 :(得分:1)

使用例如System.Net.Http.HttpClientHandlerSystem.Web.Http.HttpServer作为InnerHandler:

var handler = new FooHandler()
{
    InnerHandler = new System.Net.Http.HttpClientHandler()
};

var handler = new FooHandler()
{
    InnerHandler = new System.Web.Http.HttpServer() 
};

答案 2 :(得分:0)

使用 using Moq.Protected;,您可以更好地控制响应结果。

var request = new HttpRequestMessage();

var innerHandlerMock = new Mock<DelegatingHandler>(MockBehavior.Strict);
innerHandlerMock
  .Protected()
  .Setup<Task<HttpResponseMessage>>("SendAsync", request, ItExpr.IsAny<CancellationToken>())
  .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK));

var handler = new FooHandler()
{
  InnerHandler = innerHandlerMock.Object
};
var invoker = new HttpMessageInvoker(handler);

// act
await invoker.SendAsync(request, default);