使用System.Net.Http v4中的HttpClient的类进行单元测试

4

我希望你能翻译下面使用HttpClient的Search类单元测试,

public class Search:ISearch{
HttpClient httpClient;
  public Search(HttpClient httpClient){
   this.httpClient = httpClient;
}
   //use httClient to send request.
}

有没有一种方法可以模拟HttpClient?我在谷歌上找不到任何信息。

更新

有没有一种替代发送Http网络请求的方法,可以进行模拟。我有以下代码:

 public class Search:ISearch{
private static readonly string url = "http://www.google.com/search";
public Result SendSearch(string query){
           string queryUrl = string.Format("{0}?q={1}", url, query);
           var webRequest = WebRequest.Create(queryUrl);
          ///...
}

嗯,你真的想要模拟框架的一部分吗?我不明白这样做会给你带来什么好处,但也许我只是没有理解你的意思。 - David L
2个回答

3
在 .Net 4.5 框架中,您可以这样做。
public class FakeHttpMessageHandler : HttpMessageHandler
{
    private HttpResponseMessage response;

    public FakeHttpMessageHandler(HttpResponseMessage response)
    {
        this.response = response;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var responseTask =  new TaskCompletionSource<HttpResponseMessage>();
        responseTask.SetResult(response);

        return responseTask.Task;
    }
}


[TestMethod]
public void TestGetContents()
{
    var responseMessage = new HttpResponseMessage();
    var messageHandler = new FakeHttpMessageHandler(responseMessage);
    var client = new HttpClient(messageHandler);
    var sut = new Search(client);

    sut.SendSearch("urQuery");

    // Asserts
}

2
您不能使用像Rhino-Mocks这样的模拟框架来模拟HttpClient,因为要这样做需要在HttpClient类上有接口或虚方法。模拟框架将会为您创建一个模拟对象,该对象实现了在接口上定义的方法,或者覆盖了虚类的方法。
因此,您可以将HttpClient类包装起来,并让它实现一个接口,或者干脆不进行模拟。
如果您将代码更改为以下内容:
public class Search:ISearch
{
    private static readonly string url = "http://www.google.com/search";
    private readonly IWebRequestCreator _generator;

    public Search(IWebRequestCreator generator)
    {
        _generator = generator;
    }

    public Result SendSearch(string query)
    {
        var queryUrl = string.Format("{0}?q={1}", url, query);
        var webRequest = _generator.Create(queryUrl);
        // ...
    }
}

如果您创建了一个实现了 IWebRequestCreator 接口的类,那么您就可以模拟这个功能。实现类只需要调用 WebRequest.Create(queryUrl); 即可。

1
好的,把它包起来 :). 不确定你的 Search 调用者是如何定义的,但也许你可以从这篇文章中借鉴一些想法:https://dev59.com/IGkw5IYBdhLWcg3wirGs - bas
@Pingpong 根据你在问题中的更新进行了更新。 - bas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接