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

时间:2013-03-10 18:52:46

标签: c# unit-testing mocking

我希望单元测试下面使用HttpClient的搜索类,

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

有没有办法模拟HttpClient?我无法通过Google找到任何信息。

更新

是否有发送可以模拟的Http Web请求的替代方法。我有以下代码:

 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);
          ///...
}

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:2)

你不能用像Rhino-Mocks这样的模拟框架来模拟它,因为要做到这一点,你需要在interface类上使用virtual methodsHttpClient。模拟框架将为您创建一个模拟,它可以实现接口上定义的方法,也可以覆盖虚拟类的方法。

所以你要么包装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);