C# 5.0 wniósł wiele dobroci, m.in. obsługę wywołań asynchronicznych za pomocą słów kluczowych async
i await
. Rozwiązanie, ze względu na prostotę obsługi i skuteczność, cieszy się do dziś sporą popularnością. Jak testować wywołania asynchroniczne? Tego dowiemy się w tym odcinku!
Załóżmy, że nasza metoda testowa to asynchroniczne wywołanie dzielenia (na potrzeby artykułu dodaliśmy wywołanie Task.Delay
):
public async Task<float> DivideAsync(double dividend, double divisor)
{
if (divisor == 0) throw new DivideByZeroException();
await Task.Delay(millisecondsDelay: 1000)
.ConfigureAwait(continueOnCapturedContext: false);
return (float)dividend/(float)divisor;
}
W jaki sposób możemy napisać testy do powyższego kodu?
Najprostszy sposób przetestowania asynchronicznej metody przedstawiony jest poniżej:
[Test]
public async void DivideAsyncTest()
{
var calculator = new Calculator();
float quotient = await calculator.DivideAsync(10, 2);
Assert.That(quotient, Is.EqualTo(5));
}
async
await
i wyrażenie lambdaDrugim sposobem jest wykorzystanie wyrażeń lambda w kontekście wywołań asynchronicznych:
[Test]
public void DivideAsyncLambdaTest()
{
var calculator = new Calculator();
Assert.That(async () => await calculator.DivideAsync(10, 2), Is.EqualTo(5));
}
Aby przetestować czy asynchroniczna metoda rzuca wyjątek, możemy wykorzystać wyrażenie lambda. Tutaj test będzie wyglądać następująco:
[Test]
public void WhenDivisorIsZero_ThenDivideByZeroExceptionIsThrown()
{
var calculator = new Calculator();
Assert.Throws<DivideByZeroException>(async () => await calculator.DivideAsync(10, 0));
}
Baczny czytelnik powinien zauważyć, że najpierw napisaliśmy kod, a później testy. W tym przypadku omawiamy jednak techniczne aspekty testów jednostkowych; pisząc kod nie zapominajmy o kolejności najpierw testy, później logika biznesowa.
Kod źródłowy z tej części kursu jest dostępny na GitHubie: https://github.com/dariusz-wozniak/TddCourse/.
Część I: Testy jednostkowe – wstęp