单元测试 DelegatingHandler
Unit testing 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, "");
您可以使用 dummy/fake 处理程序 (TestHandler
) 设置您正在测试的 DelegatingHandler (FooHandler
) 的 InnerHandler
属性,如图所示在您的评论中 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, "https://example.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, "");
与 post 不同,这应该是使测试达到 运行 所需的最低设置。
使用例如System.Net.Http.HttpClientHandler or System.Web.Http.HttpServer 作为 InnerHandler:
var handler = new FooHandler()
{
InnerHandler = new System.Net.Http.HttpClientHandler()
};
或
var handler = new FooHandler()
{
InnerHandler = new System.Web.Http.HttpServer()
};
使用 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);
如何对自定义 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, "");
您可以使用 dummy/fake 处理程序 (TestHandler
) 设置您正在测试的 DelegatingHandler (FooHandler
) 的 InnerHandler
属性,如图所示在您的评论中 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, "https://example.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, "");
与 post 不同,这应该是使测试达到 运行 所需的最低设置。
使用例如System.Net.Http.HttpClientHandler or System.Web.Http.HttpServer 作为 InnerHandler:
var handler = new FooHandler()
{
InnerHandler = new System.Net.Http.HttpClientHandler()
};
或
var handler = new FooHandler()
{
InnerHandler = new System.Web.Http.HttpServer()
};
使用 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);