我看到这个问题出现在几个地方,但没有看到任何好的答案。因为我不得不自己做几次,所以我想我应该发布我的解决方案。如果你有更好的,请发布。
注意这是使用 ASP.NET MVC 4 Beta 2 版本的 Web API - future 版本可能会改变!
更新:这在 ASP.NET MVC 4 RC 中仍然有效
最佳答案
在这种方法中,我创建了一个 TestHandler 并将其设置为被测处理程序的 InnerHandler
属性。
然后可以将被测处理程序传递给 HttpClient
- 如果您正在编写服务器端处理程序,这可能看起来不直观,但这实际上是测试处理程序的一种很好的轻量级方法- 它将以与在服务器中相同的方式被调用。
默认情况下,TestHandler 只会返回 HTTP 200,但它的构造函数接受一个函数,您可以使用该函数对传递的请求消息进行断言 来自被测处理程序。最后,您可以对来自客户端的 SendAsync 调用的结果进行断言。
一切设置完成后,在客户端实例上调用 SendAsync
以调用您的处理程序。该请求将被传递到您的处理程序中,它会将此传递给 TestHandler(假设它通过调用),然后它将响应返回给您的处理程序。
测试处理程序如下所示:
public class TestHandler : DelegatingHandler
{
private readonly Func<HttpRequestMessage,
CancellationToken, Task<HttpResponseMessage>> _handlerFunc;
public TestHandler()
{
_handlerFunc = (r, c) => Return200();
}
public TestHandler(Func<HttpRequestMessage,
CancellationToken, Task<HttpResponseMessage>> handlerFunc)
{
_handlerFunc = handlerFunc;
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
return _handlerFunc(request, cancellationToken);
}
public static Task<HttpResponseMessage> Return200()
{
return Task.Factory.StartNew(
() => new HttpResponseMessage(HttpStatusCode.OK));
}
}
在测试中想象的 MyHandler
的用法示例。使用 NUnit 作为断言。:
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://test.com");
httpRequestMessage.Headers.Add("username", "test");
var handler = new MyHandler()
{
InnerHandler = new TestHandler((r,c) =>
{
Assert.That(r.Headers.Contains("username"));
return TestHandler.Return200();
})
};
var client = new HttpClient(handler);
var result = client.SendAsync(httpRequestMessage).Result;
Assert.That(result.StatusCode, Is.EqualTo(HttpStatusCode.OK));
TestHandler 的默认行为可能适用于许多测试并使代码更简单。被测处理程序的设置如下所示:
var handler = new MyHandler();
handler.InnerHandler = new TestHandler();
我喜欢这种方法,因为它保留了测试方法中的所有断言,而且 TestHandler
非常可重用。
关于c# - 如何在 ASP.NET MVC 4 Web API 中测试自定义 DelegatingHandler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9789944/