c# - 如何在 ASP.NET MVC 4 Web API 中测试自定义 DelegatingHandler?

标签 c# asp.net-mvc unit-testing asp.net-mvc-4 asp.net-web-api

我看到这个问题出现在几个地方,但没有看到任何好的答案。因为我不得不自己做几次,所以我想我应该发布我的解决方案。如果你有更好的,请发布。

注意这是使用 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/

相关文章:

c# - 将类型为 `Kendo.Mvc.UI.DataSourceRequest` 的对象从 jquery 传递到 Mvc Action

javascript - 如何在 ASP.Net MVC 4 中为日期选择器添加 javascript

c# - .net Core X Forwarded Proto 不工作

angularjs - 我应该在 AngularJS 中测试什么?

angularjs - 使用 Jasmine 和 Karma 在 AngularJS 中对具有依赖性的工厂进行单元测试失败

javascript - 使用 ajax 请求序列化带有 html 值的输入

c# - ngrok + 本地 IIS : how to expose a website

c# - TreeView(带有复选框)没有正确处理点击?

asp.net-mvc - 当匹配不包含该参数的路由时,ActionLinks 恢复为查询字符串参数

swift - 单元测试 VIPER 协议(protocol)