Przygotowuję niektóre testy jednostkowe i za pomocą Rhino Mocks do wypełnienia testowanego obiektu. Jedną z rzeczy, które są wyśmiewane, jest Task<HttpResponseMessage>
, ponieważ testowana logika obejmuje wywołanie do HttpClient
, aby uzyskać odpowiedź asynchroniczną.Jak wyśmiać zadanie <> Wynik?
Więc zacząłem ustanowienia mocks jak to:
var httpClient = MockRepository.GenerateMock<HttpClient>();
var taskFunc = MockRepository.GenerateMock<Func<HttpResponseMessage>>();
var responseTask = MockRepository.GenerateMock<Task<HttpResponseMessage>>(taskFunc);
var response = MockRepository.GenerateMock<HttpResponseMessage>();
httpClient.Stub(c => c.PostAsJsonAsync<IEnumerable<LogMessage>>(Arg<string>.Is.Anything, Arg<IEnumerable<LogMessage>>.Is.Anything)).Return(responseTask);
responseTask.Stub(t => t.Result).Return(response);
response.Stub(r => r.IsSuccessStatusCode).Return(true);
(„Ustawa” krok testu będzie instancję obiektu badanego, paszy mu httpClient
i uruchomić metodę . na to „dochodzić” zweryfikuje poprzez mocks że oczekiwane wywołania metod dokonano na nich)
Krocząc przez to w debugger, jest nieokreślony zawiesić na tej linii.
responseTask.Stub(t => t.Result).Return(response);
Nie mam dużego doświadczenia z Rhino Mocks lub z asynchronizacją C#, więc mogę przeoczyć coś oczywistego. Celem jest oczywiście, aby każde połączenie z właściwością .Result
zwróciło próbę response
. Ale wygląda na to, że moja próba sama w sobie może wywołać .Result
, czego oczekiwałbym w nieskończoność, skoro jest to tylko udawanie?
Jaki jest właściwy sposób aranżacji? Zasadniczo muszę dostarczyć mój obiekt z wyszydzanym HttpClient
i potwierdzić, że metoda została wywołana na nim z określonym argumentem.
Zrobiłem dużo szyderstwa wokół zadań około roku temu przy użyciu MOQ. O ile się nie mylę, wystarczy zastąpić komunikat taskFunc, który przechodzisz, do swojej fałszywej odpowiedzi. Następnie ta funkcja próbna natychmiast zwróci odpowiedź. – Keith
@Keith: Interesujące. Więc po prostu stwórz prawdziwe 'Func' zamiast makiety, która tylko zwraca? Po prostu próbowałem jako takie: 'Func taskFunc = delegate() {return response; }; 'i przekazane, że' taskFunc' na próbę 'responseTask', ale zachowuje się to samo zachowanie. –
David
Nie sądzę, że potrzebujesz rzeczywistego zadania próbnego. To, czego potrzebujesz do makiety, to funkcja przekazywana do zadania, więc po prostu zwróci "x". – Keith