如何简单地将
mock
注入到SingleHttpClientInstanceController
的private static readonly HttpClient
字段中?
答案:没有简单的方法。
建议:
通过访问器来抽象资源
public interface IHttpClientAccessor {
HttpClient HttpClient { get; }
}
public class SingleHttpClientInstanceController : ApiController {
private readonly HttpClient HttpClient;
public SingleHttpClientInstanceController(IHttpClientAccessor httpClientAccessor) {
HttpClient = httpClientAccessor.HttpClient;
}
// This method uses the shared instance of HttpClient for every call to GetProductAsync.
public async Task<Product> GetProductAsync(string id) {
var hostName = HttpContext.Current.Request.Url.Host;
var result = await HttpClient.GetStringAsync(string.Format("http://{0}:8080/api/...", hostName));
return new Product { Name = result };
}
}
同样的操作也应该用于访问HttpContext
,这是最近在Asp.Net-Core中引入的IHttpContextAccessor
IHttpClientAcessor
的实现可以像这样:
public class HttpClientAccessor : IHttpClientAccessor {
static readonly Lazy<HttpClient> client = new Lazy<HttpClient>(() => new HttpClient());
public HttpClient HttpClient { get { return client.Value; } }
}
现在,为了测试,您可以注入依赖项的模拟。
如果使用DI容器,请记得将访问者也注册为单例。