繁体   English   中英

单元测试使用HttpClient发出Http请求的Controller

[英]Unit testing a Controller that makes Http requests using HttpClient

我需要为这个控制器编写单元测试(最重要的是,我被要求获得代码覆盖)。

public class MyController : Controller
{
    public async Task<ActionResult> Index()
    {
        ViewBag.Title = "Home Page";
        var httpClient = new HttpClient();
        var json = await httpClient.GetStringAsync(ConfigurationManager.AppSettings["MyCustomAPI"]);
        var tasks = JsonConvert.DeserializeObject<List<MyObject>>(json);
        return View(tasks);
    }
}

我一直在阅读关于这个问题的两天的想法,但我无法绕过它。

我一直在考虑像这样注入HttpClient:

    private readonly HttpClient _httpClient;

    public TasksController(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

但是在控制器构造函数中传递HttpClient可能不是一个好主意。

然后我一直在遵循使用FakeItEasy的指南,但我无法根据我的要求调整此解决方案。

我该如何进行测试呢?

将您的http工作提取到一个接口,并将该接口的实现注入您的控制器。

public interface INetworkService {
  Task<List<MyObject>> GetThingsAsync(string api);
}

public class HttpNetworkService : INetworkService {
  private readonly HttpClient Client;
  public HttpNetworkService(HttpClient client) {
    Client = client;
  }

  public Task<List<MyObject>> GetThingsAsync(string api) {
    var json = await Client.GetStringAsync(api);
    return JsonConvert.DeserializeObject<List<MyObject>>(json);
  }
}

public class TestNetworkService : INetworkService {
  public Task<List<MyObject>> GetThingsAsync(string api) {
    return Task.FromResult(new List<MyObject> { /*build out your mock result here*/ });
  }
}

public class MyController : Controller {
  private readonly INetworkService NetworkService;
  public MyController(INetworkService svc) {
    NetworkService = svc;
  }

  public async Task<ActionResult> Index() {
    ViewBag.Title = "Home Page";
    var tasks = await NetworkService.GetThingsAsync(ConfigurationManager.AppSettings["MyCustomAPI"]);
    return View(tasks);
  }
}

现在,当您进行测试时,您可以在INetworkService的测试版本中进行子操作,该测试版本实际上不会执行任何联网的IO。 此外,正如评论中所提到的,您应该共享一个HttpClient而不是一直创建新的HttpClient,该客户端可以注入到真正的INetworkedService实现中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM