在单元测试中模拟HttpClient

我在尝试包装要在单元测试中使用的代码时遇到了一些问题。问题是这样的。我有接口IHttpHandler:

public interface IHttpHandler

{

HttpClient client { get; }

}

和使用它的类,HttpHandler:

public class HttpHandler : IHttpHandler

{

public HttpClient client

{

get

{

return new HttpClient();

}

}

}

然后是Connection类,该类使用simpleIOC注入客户端实现:

public class Connection

{

private IHttpHandler _httpClient;

public Connection(IHttpHandler httpClient)

{

_httpClient = httpClient;

}

}

然后我有一个具有此类的单元测试项目:

private IHttpHandler _httpClient;

[TestMethod]

public void TestMockConnection()

{

var client = new Connection(_httpClient);

client.doSomething();

// Here I want to somehow create a mock instance of the http client

// Instead of the real one. How Should I approach this?

}

现在显然我将在Connection类中具有从后端检索数据(JSON)的方法。但是,我想为此类编写单元测试,显然我不想针对真正的后端编写测试,而只是想模拟一个后端。我曾试图用谷歌搜索一个很好的答案,但没有成功。我可以并且曾经使用过Moq进行模拟,但是从未使用过诸如httpClient之类的东西。我应该如何解决这个问题?

提前致谢。

回答:

您的接口公开了具体的HttpClient类,因此,使用该接口的所有类都将与其绑定在一起,这意味着无法对其进行模拟。

HttpClient不会从任何接口继承,因此您必须编写自己的接口。我建议一种 模式:

public interface IHttpHandler

{

HttpResponseMessage Get(string url);

HttpResponseMessage Post(string url, HttpContent content);

Task<HttpResponseMessage> GetAsync(string url);

Task<HttpResponseMessage> PostAsync(string url, HttpContent content);

}

您的课程将如下所示:

public class HttpClientHandler : IHttpHandler

{

private HttpClient _client = new HttpClient();

public HttpResponseMessage Get(string url)

{

return GetAsync(url).Result;

}

public HttpResponseMessage Post(string url, HttpContent content)

{

return PostAsync(url, content).Result;

}

public async Task<HttpResponseMessage> GetAsync(string url)

{

return await _client.GetAsync(url);

}

public async Task<HttpResponseMessage> PostAsync(string url, HttpContent content)

{

return await _client.PostAsync(url, content);

}

}

所有这些的关键是HttpClientHandler创建自己的HttpClient,然后您当然可以创建IHttpHandler以不同方式实现的多个类。

这种方法的主要问题是,您正在有效地编写一个仅在另一个类中调用方法的类,但是您可以创建一个 自该类的类HttpClient(请参阅

,这比我的方法要好得多)。如果HttpClient拥有一个您可以嘲笑的界面,生活会容易得多,但不幸的是,它却没有。

但是,此示例

黄金票。IHttpHandler仍然依赖于HttpResponseMessage,它属于System.Net.Http名称空间,因此,如果您确实需要除以外的其他实现HttpClient,则必须执行某种映射以将其响应转换为HttpResponseMessage对象。当然,这仅是一个问题,

IHttpHandler但看起来却并非如此,这不是世界末日,而是要考虑的问题。

无论如何,您可以简单地进行模拟,IHttpHandler而不必担心具体HttpClient类被抽象化了。

我建议测试

方法,因为它们仍然调用异步方法,而不必担心单元测试异步方法的麻烦,请参见此处

以上是 在单元测试中模拟HttpClient 的全部内容, 来源链接: utcz.com/qa/418920.html

回到顶部