Ich habe eine Klasse, die auf den HttpClient von Windows.Web.Http (Windows 10 UAP App) abhängt. Ich möchte einen Komponententest durchführen und muss daher den HttpClient "überspielen", um festzulegen, was ein Get-Call zurückgeben soll. Ich begann mit einem "einfachen" Komponententest mit einem HttpClient unter Verwendung eines handgeschriebenen-verspotteten IHttpFilter und IHttpContent. Es funktioniert nicht wie erwartet und ich bekomme eine InvalidCastException im Test-Explorer.Unit Test Windows.Web.Http HttpClient mit mocked IHttpFilter und IHttpContent, MockedHttpFilter wirft System.InvalidCastException
Der Unit-Test wie folgt aussieht:
[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);
}
I IHttpFilter in MockedHttpFilter umgesetzt:
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...
}));
}
}
I IHttpContent in MockedHttpContent umgesetzt:
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;
}));
}
}
Der Fehler in dem Test Explorer Ergebnisansicht:
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.
Erstens, nicht sicher, warum die Ausnahme ausgelöst wird/was ich falsch mache. Vielleicht kann mir jemand in die richtige Richtung zeigen oder einen Hinweis geben, was ich als nächstes prüfen/testen soll?
Zweitens gibt es eine bessere Möglichkeit, Testcode mit einer HttpClient Abhängigkeit (Windows 10 UAP) zu verbinden?
Haben Sie Ihr Problem gelöst? Das interessiert mich auch. – Corcus
Leider nicht. Wegen hoher Arbeitsbelastung, Stress zu Hause und an der Universität kann ich momentan nicht an meinem privaten Projekt arbeiten. – 1ppCH
Dies ist nicht wirklich der Weg zum Komponententest, sollten Sie externe Abhängigkeiten und dann nur Unit-Test-Code, den Sie die volle Kontrolle über haben. Das Einbringen von Mocks in ein Framework, das Sie nicht kontrollieren können, scheint falsch zu sein, mit Ausnahme von spezifischen Komponententests. Ein anderes Problem ist, dass der Rückgabetyp für [TestMethod] nicht ungültig sein sollte? –