Pur*_*ome 7 .net c# unit-testing fakeiteasy
我试图弄清楚如何使用HttpClient使用FakeItEasy,给出以下代码:
public Foo(string key, HttpClient httpClient = null)
{ .. }
public void DoGet()
{
....
if (_httpClient == null)
{
_httpClient = new HttpClient();
}
var response = _httpClient.GetAsync("user/1);
}
public void DoPost(foo Foo)
{
if (_httpClient == null)
{
_httpClient = new HttpClient();
}
var formData = new Dictionary<string, string>
{
{"Name", "Joe smith"},
{"Age", "40"}
};
var response = _httpClient.PostAsync("user",
new FormUrlEncodedContent(formData));
}
Run Code Online (Sandbox Code Playgroud)
所以我不知道如何使用FakeItEasy,伪造出HttpClient GetAsync和PostAsync方法.
生产代码不会在HttpClient中传递,但单元测试将传递由FakeItEasy制作的假实例.
例如.
[Fact]
public void GivenBlah_DoGet_DoesSomething()
{
// Arrange.
var httpClient A.Fake<HttpClient>(); // <-- need help here.
var foo = new Foo("aa", httpClient);
// Act.
foo.DoGet();
// Assert....
}
Run Code Online (Sandbox Code Playgroud)
我认为FiE(以及大多数模拟软件包)可以在接口或虚拟方法上运行.因此,对于这个问题,让刚刚prentend的GetAsync和PostAsync方法是虚拟化......请:)
Cra*_* W. 12
这是我的(或多或少)通用FakeHttpMessageHandler.
public class FakeHttpMessageHandler : HttpMessageHandler
{
private HttpResponseMessage _response;
public static HttpMessageHandler GetHttpMessageHandler( string content, HttpStatusCode httpStatusCode )
{
var memStream = new MemoryStream();
var sw = new StreamWriter( memStream );
sw.Write( content );
sw.Flush();
memStream.Position = 0;
var httpContent = new StreamContent( memStream );
var response = new HttpResponseMessage()
{
StatusCode = httpStatusCode,
Content = httpContent
};
var messageHandler = new FakeHttpMessageHandler( response );
return messageHandler;
}
public FakeHttpMessageHandler( HttpResponseMessage response )
{
_response = response;
}
protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken )
{
var tcs = new TaskCompletionSource<HttpResponseMessage>();
tcs.SetResult( _response );
return tcs.Task;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我的一个测试中使用它的一个例子,它希望将一些JSON作为返回值.
const string json = "{\"success\": true}";
var messageHandler = FakeHttpMessageHandler.GetHttpMessageHandler(
json, HttpStatusCode.BadRequest );
var httpClient = new HttpClient( messageHandler );
Run Code Online (Sandbox Code Playgroud)
你现在将httpClient注入你正在测试的类中(使用你喜欢的任何注入机制),当GetAsync你被调用时,你messageHandler会吐出你告诉它的结果.
您还可以创建一个AbstractHandler可以拦截公共抽象方法的方法。例如:
public abstract class AbstractHandler : HttpClientHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return Task.FromResult(SendAsync(request.Method, request.RequestUri.AbsoluteUri));
}
public abstract HttpResponseMessage SendAsync(HttpMethod method, string url);
}
Run Code Online (Sandbox Code Playgroud)
然后你可以拦截类似的调用AbstractHandler.SendAsync(HttpMethod method, string url):
// Arrange
var httpMessageHandler = A.Fake<AbstractHandler>(options => options.CallsBaseMethods());
A.CallTo(() => httpMessageHandler.SendAsync(A<HttpMethod>._, A<string>._)).Returns(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Result")});
var httpClient = new HttpClient(httpMessageHandler);
// Act
var result = await httpClient.GetAsync("https://google.com/");
// Assert
Assert.Equal("Result", await result.Content.ReadAsStringAsync());
A.CallTo(() => httpMessageHandler.SendAsync(A<HttpMethod>._, "https://google.com/")).MustHaveHappenedOnceExactly();
Run Code Online (Sandbox Code Playgroud)
更多信息可以在此博客上找到:https://www.meziantou.net/mocking-an-httpclient-using-an-httpclienthandler.htm
| 归档时间: |
|
| 查看次数: |
4509 次 |
| 最近记录: |