为“私有静态只读”字段创建存根
Creating stub for `private static readonly` field
由于 Improper Instantiation problem 建议创建 private static readonly
个 HttpClient
实例。
由于时间不够,我将 mocked
client 注入到测试方法中,并以 client
作为参数。
问题是我如何以简单的方式将 mock
注入 SingleHttpClientInstanceController
的 private static readonly HttpClient
字段?
how can I in simple way inject mock
into private static readonly
HttpClient
field of SingleHttpClientInstanceController
?
答:没有简单的方法。
建议:
抽象访问器后面的资源
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 容器,请记得将访问器也注册为单例。
由于 Improper Instantiation problem 建议创建 private static readonly
个 HttpClient
实例。
由于时间不够,我将 mocked
client 注入到测试方法中,并以 client
作为参数。
问题是我如何以简单的方式将 mock
注入 SingleHttpClientInstanceController
的 private static readonly HttpClient
字段?
how can I in simple way inject
mock
intoprivate static readonly HttpClient
field ofSingleHttpClientInstanceController
?
答:没有简单的方法。
建议:
抽象访问器后面的资源
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 容器,请记得将访问器也注册为单例。