1pp*_*pCH 13 c# unit-testing win-universal-app windows-10
我有一个类依赖于Windows.Web.Http(Windows 10 UAP App)中的HttpClient.我想进行单元测试,因此我需要"模拟"HttpClient来设置Get-Call应返回的内容.我开始使用HttpClient进行"简单"的单元测试,使用手写模拟的IHttpFilter和IHttpContent.它没有按预期工作,我在Test-Explorer中得到一个InvalidCastException.
单元测试看起来像:
[TestMethod]
public async Task TestMockedHttpFilter()
{
MockedHttpContent mockedContent = new MockedHttpContent("Content from MockedHttpContent");
MockedHttpFilter mockedHttpFilter = new MockedHttpFilter(HttpStatusCode.Ok, mockedContent);
HttpClient httpClient = new HttpClient(mockedHttpFilter);
var resultContentTask = await httpClient.SendRequestAsync(new HttpRequestMessage(HttpMethod.Get, new Uri("http://dontcare.ch"))).AsTask().ConfigureAwait(false);
// Test stops here, throwing System.InvalidCastException: Specified cast is not valid
// Code not reached...
var result = await resultContentTask.Content.ReadAsStringAsync();
Assert.AreEqual("Content from MockedHttpContent", result);
}
Run Code Online (Sandbox Code Playgroud)
我在MockedHttpFilter中实现了IHttpFilter:
public class MockedHttpFilter : IHttpFilter
{
private HttpStatusCode _statusCode;
private IHttpContent _content;
public MockedHttpFilter(HttpStatusCode statusCode, IHttpContent content)
{
_statusCode = statusCode;
_content = content;
}
public IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> SendRequestAsync(HttpRequestMessage request)
{
return AsyncInfo.Run<HttpResponseMessage, HttpProgress>((token, progress) =>
Task.Run<HttpResponseMessage>(()=>
{
HttpResponseMessage response = new HttpResponseMessage(_statusCode);
response.Content = _content;
return response; // Exception thrown after return, but not catched by code/debugger...
}));
}
}
Run Code Online (Sandbox Code Playgroud)
我在MockedHttpContent中实现了IHttpContent:
public class MockedHttpContent : IHttpContent
{
private string _contentToReturn;
public MockedHttpContent(string contentToReturn)
{
_contentToReturn = contentToReturn;
}
public HttpContentHeaderCollection Headers
{
get
{
return new HttpContentHeaderCollection();
}
}
public IAsyncOperationWithProgress<string, ulong> ReadAsStringAsync()
{
return AsyncInfo.Run<string, ulong>((token, progress) => Task.Run<string>(() =>
{
return _contentToReturn;
}));
}
}
Run Code Online (Sandbox Code Playgroud)
Test-Explorer结果视图中的错误:
Test Name: TestMockedHttpFilter
Test FullName: xxx.UnitTests.xxxHttpClientUnitTests.TestMockedHttpFilter
Test Source: xxx.UnitTests\xxxHttpClientUnitTests.cs : line 22
Test Outcome: Failed
Test Duration: 0:00:00.1990313
Result StackTrace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at xxx.UnitTests.xxxHttpClientUnitTests.<TestMockedHttpFilter>d__1.MoveNext()
--- 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)
Result Message: Test method xxx.UnitTests.xxxHttpClientUnitTests.TestMockedHttpFilter threw exception:
System.InvalidCastException: Specified cast is not valid.
Run Code Online (Sandbox Code Playgroud)
首先,不确定抛出异常的原因/我做错了什么.也许有人可以指出我正确的方向或提示下一步检查/测试什么?
其次,是否有更好的方法来使用HttpClient依赖(Windows 10 UAP)对代码进行单元测试?
看来您没有使用AsTask与返回值匹配的重载httpClient.SendRequestAsync(...)
尝试改变这个
var resultContentTask = await httpClient.SendRequestAsync(new HttpRequestMessage(HttpMethod.Get, new Uri("http://dontcare.ch"))).AsTask().ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
对此
var resultContentTask = await httpClient.SendRequestAsync(new HttpRequestMessage(HttpMethod.Get, new Uri("http://dontcare.ch"))).AsTask<IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress>>().ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)