c# - 如何在 .NET 测试中传入模拟的 HttpClient?

标签 c# .net mocking dotnet-httpclient microsoft-fakes

我有一项服务使用 Microsoft.Net.Http 来检索一些 Json 数据。太棒了!

当然,我不希望我的单元测试命中实际服务器(否则,那是一个集成测试)。

这是我的服务构造器(它使用依赖注入(inject)...)

public Foo(string name, HttpClient httpClient = null)
{
...
}

我不确定如何用...来模拟这个...说 .. MoqFakeItEasy

我想确保当我的服务调用 GetAsyncPostAsync .. 然后我可以伪造这些调用。

有什么建议吗?

我 - 希望 - 我不需要制作自己的 Wrapper .. 因为那是废话 :( Microsoft 不能对此进行疏忽,对吧?

(是的,制作 wrapper 很容易……我以前做过……但这就是重点!)

最佳答案

您可以用假的替换核心 HttpMessageHandler。看起来像这样的东西......

public class FakeResponseHandler : DelegatingHandler
{
    private readonly Dictionary<Uri, HttpResponseMessage> _FakeResponses = new Dictionary<Uri, HttpResponseMessage>();

    public void AddFakeResponse(Uri uri, HttpResponseMessage responseMessage)
    {
        _FakeResponses.Add(uri, responseMessage);
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        if (_FakeResponses.ContainsKey(request.RequestUri))
        {
            return Task.FromResult(_FakeResponses[request.RequestUri]);
        }
        else
        {
            return Task.FromResult(new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request });
        }
    }
}

然后您可以创建一个将使用假处理程序的客户端。

var fakeResponseHandler = new FakeResponseHandler();
fakeResponseHandler.AddFakeResponse(new Uri("http://example.org/test"), new HttpResponseMessage(HttpStatusCode.OK));

var httpClient = new HttpClient(fakeResponseHandler);

var response1 = await httpClient.GetAsync("http://example.org/notthere");
var response2 = await httpClient.GetAsync("http://example.org/test");

Assert.Equal(response1.StatusCode,HttpStatusCode.NotFound);
Assert.Equal(response2.StatusCode, HttpStatusCode.OK);

关于c# - 如何在 .NET 测试中传入模拟的 HttpClient?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22223223/

相关文章:

c# - Linq 返回字符串

rest - 在模拟服务 URL 中使用通配符

c# - 如何使用 Moq 测试没有返回值的方法?

c# - 在 C# 中使用元组,(A, B, C) vs Tuple<string, string, string>

c# - 如何允许两个具有相同 namespace.class 的 DLL 存在于同一个应用程序中?

C# AddMemoryPressure 性能

c# - 如何使面板控件显示在所有其他控件下方?

c# - 指定的初始化向量 (IV) 与该算法的 block 大小不匹配

c# - 在运行时已知类型时如何将对象转换为类型?

c# - SimpleStub 中 MockBehavior.Loose 和 MockBehavior.Strict 有什么区别?