我使用的一个项目新的Web API位,我发现,我不能正常使用的HttpMessageRequest
,因为我需要客户端证书添加到请求。 其结果是,我使用的是HttpClient
(这样我就可以使用WebRequestHandler
)。 这一切运作良好,但它不是存根/模拟友好,至少犀牛制品。
我通常会创建一个围绕包装服务HttpClient
,我会改用,但我想如果可能避免这一点,因为有很多的,我需要换行的方法。 我希望,我已经失去了一些东西,任何关于如何存根建议HttpClient
?
我用的起订量,我可以存根出HttpClient的。 我想,这对于犀牛素(我还没有我自己试过)相同。 如果你只是想存根的HttpClient下面的代码应该工作:
var stubHttpClient = new Mock<HttpClient>();
ValuesController controller = new ValuesController(stubHttpClient.Object);
如果我错了请纠正我。 我想你指的是这里是内HttpClient的磕碰出的成员。
最受欢迎的隔离/模拟对象框架不会让你来,踩在非虚拟成员例如/设置下面的代码抛出一个异常
stubHttpClient.Setup(x => x.BaseAddress).Returns(new Uri("some_uri");
你也提到你想避免创造一个包装,因为你会换很多HttpClient的成员。 尚不清楚为什么你需要用很多的方法,但你可以很容易地只换你所需要的方法。
例如 :
public interface IHttpClientWrapper { Uri BaseAddress { get; } }
public class HttpClientWrapper : IHttpClientWrapper
{
readonly HttpClient client;
public HttpClientWrapper() {
client = new HttpClient();
}
public Uri BaseAddress {
get
{
return client.BaseAddress;
}
}
}
我认为可能会为你(很多例子,在那里,所以我不会写代码)微软痣框架中受益的其他选项http://research.microsoft.com/en-us/projects/moles/微软正版正货承诺:(如果你正在使用VS2012旗舰版) http://msdn.microsoft.com/en-us/library/hh549175.aspx
作为替代已经@Raj提出的优秀的想法,有可能走了一步低,嘲笑/伪造HttpMessageHandler
代替。
如果您需要任何一类HttpClient
接受它作为构造函数依赖注入参数,然后在单元测试时,可以在传递HttpClient
已经注射用自己的HttpMessageHandler
。 这个简单的类只有一个,你需要实现,如下抽象方法:
public class FakeHttpMessageHandler : HttpMessageHandler
{
public HttpRequestMessage RequestMessage { get; private set; }
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
RequestMessage = request;
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));
}
}
我简单的例子只是保存HttpRequestMessage
的公共属性以备日后检查,并返回HTTP 200(OK),但你可以通过添加一个构造函数,设置您希望返回的结果扩大此。
你会使用这个类是这样的:
public void foo()
{
//Arrange
var fakeHandler = new FakeHttpMessageHandler();
var client = new HttpClient(fakeHandler);
var SUT = new ClassUnderTest(client);
//Act
SUT.DomSomething();
//Assert
fakeHandler.RequestMessage.Method.ShouldEqual(HttpMethod.Get); // etc...
}
有局限性这种方法,例如,使多个请求或需要创建多个方法HttpClient
s,则假处理程序可能会开始变得太复杂。 但是,它可能是值得考虑的简单情况。
我发布了一个库几个月前称为MockHttp这可能是有用的。 它使用了自定义HttpMessageHandler
用流利的(和可扩展)API。 你可以注入嘲笑的处理程序(或HttpClient的)到您的服务类,因为它是配置它会回应。
下面显示的基本用法。 在When
和Respond
方法,有一大堆的重载,包括运行自定义逻辑的。 在GitHub的页面文件进入到更多细节。
var mockHttp = new MockHttpMessageHandler();
// Setup a respond for the user api (including a wildcard in the URL)
mockHttp.When("http://localhost/api/user/*")
.Respond("application/json", "{'name' : 'Test McGee'}"); // Respond with JSON
// Inject the handler or client into your application code
var client = new HttpClient(mockHttp);
var response = async client.GetAsync("http://localhost/api/user/1234");
// or without async: var response = client.GetAsync(...).Result;
var json = await response.Content.ReadAsStringAsync();
// No network connection required
Console.Write(json); // {'name' : 'Test McGee'}