创建一个模拟的IHttpFilter来测试Windows.Web.Http.HttpClient
本文关键字:测试 Windows Web HttpClient Http IHttpFilter 模拟 一个 创建 | 更新日期: 2023-09-27 18:34:26
我想创建一个"模拟"IHttpFilter
实现,用于测试Windows.Web.Http HttpClient
调用。这是我在实现中的发送请求异步方法
public IAsyncOperationWithProgress<HttpResponseMessage,HttpProgress>
SendRequestAsync(HttpRequestMessage request)
{
HttpResponseMessage response = new HttpResponseMessage(_statusCode);
response.Content = _content;
//This is the problematic part
return AsyncInfo.Run<HttpResponseMessage, HttpProgress>(
(token, progress) => Task.Run<HttpResponseMessage>(
() => { return response; }));
}
在我的测试方法中,我是这样使用它的。这也是在应用程序中使用HttpClient
的方式。
//This Throws an InvalidCastException
var result = await client.SendRequestAsync(new HttpRequestMessage(HttpMethod.Get, new Uri("http://www.nomatter.com")));
但它抛出了一个 InvalidCastException
Result Message: Test method UnitTestLibrary1.UnitTest.TestHttp threw exception:
System.InvalidCastException: Specified cast is not valid.
Result StackTrace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at UnitTestLibrary1.UnitTest.<TestHttp>d__0.MoveNext() in c:'Users'****'UniversalPCLUnitTest'UnitTestLibrary1'UnitTest1.cs:line 40
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
我无法找出为什么会抛出异常。有没有人遇到同样的问题??
这个问题有两个答案。
第一个答案是,你甚至不应该尝试模拟一个System.Net.HttpClient。此类应在应用中实例化一次,可能作为单一实例。
您通常会将HttpClient的使用包装到某种合约中,即IE
public interface ICanGetHttpBodies{
string AsString(Uri uri);
}
然后,当然,使用该合约,并在需要时模拟它:
[TestMethod, ExpectedException(typeof(ProgramException))]
public void MyMethod_WhenEmptyBody_ThrowsException()
{
// Arrange
var emptyBody = "";
var getBodyMock = new Mock<ICanGetHttpBodies>()
.Setup(m => m.AsString(It.IsAny<Uri>())
.Returns(emptyBody);
// Act & Assert
}
这样,您就可以完全控制代码流,将HttpClient隐藏在赋予您含义的合约中(ICanGetHttpBodies),这也使代码更易于阅读(免费奖金:)
第二个答案是,Visual Studio中有一种叫做"Fakes"的东西,它可以让你能够存根/模拟静态库,如HttpClient和DateTime:
https://msdn.microsoft.com/en-us/library/hh549175.aspx
希望这些对您有所帮助,并且您更喜欢答案选项 1 :)