![](/img/trans.png)
[英]Unit Testing Core API Controller Using Custom HttpClient and Polly policy within ConfigureServices
[英]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.