Cvičení – test jednotek funkce Azure Functions
Testování jednotek je základní součástí agilní metodologie. V sadě Visual Studio je k dispozici šablona projektu testů. Pomocí této šablony vytvoříte testy jednotek pro aplikace a stejný postup můžete použít k testování Azure Functions.
Ve scénáři online webu luxusních hodinek má váš vývojový tým zásady pro dosažení alespoň 80% pokrytí kódu při testování jednotek. Chcete implementovat stejné zásady pro Azure Functions.
Tady se dozvíte, jak pomocí xUnit
testovací architektury se sadou Visual Studio otestovat Azure Functions.
Vytvoření projektu testů jednotek
Prvním krokem je vytvoření projektu, který obsahuje testy jednotek, a jeho přidání do řešení, které obsahuje vaši aplikaci Funkcí Azure. Pomocí následujících kroků můžete vytvořit projekt testů jednotek pro testování funkce WatchInfo.
V sadě Visual Studio v okně Průzkumníka řešení klikněte pravým tlačítkem na řešení WatchPortalFunction, vyberte Přidat a potom zvolte Nový projekt.
V okně Přidat nový projekt se posuňte dolů, vyberte šablonu ikony xUnit Test Project C#+ a pak vyberte Další.
Objeví se okno Konfigurovat nový projekt. Do pole Název projektu zadejte WatchFunctionsTests. Vedle pole Umístění vyberte ikonu pro procházení a pak vyberte složku WatchPortalFunction.
Vyberte Další. Zobrazí se okno Další informace .
V části Cílová architektura. přijměte výchozí hodnotu rozhraní .NET 6.0 (dlouhodobá podpora).
Vyberte Vytvořit.
Po přidání projektu klikněte pravým tlačítkem myši na projekt WatchFunctionTests v okně Průzkumník řešení a pak vyberte Spravovat balíčky NuGet.
V okně NuGet: WatchFunctionTests vyberte kartu Procházet. Do vyhledávacího pole zadejte Microsoft.AspNetCore.Mvc. Vyberte balíček Microsoft.AspNetCore.Mvc a pak zvolte Nainstalovat.
Poznámka:
Projekt testů vytvoří napodobeninu prostředí HTTP. Třídy, které jsou k tomu třeba, jsou v balíčku Microsoft.AspNetCore.Mvc.
Počkejte, než se balíček nainstaluje. Pokud se zobrazí okno se zprávou Náhled změn, vyberte OK. V okně se zprávou Souhlas s podmínkami licence zvolte Přijmout.
Po přidání balíčku klikněte v okně Průzkumník řešení v projektu WatchFunctionsTests pravým tlačítkem myši na soubor UnitTest1.cs a pak vyberte Přejmenovat. Změňte název souboru na WatchFunctionUnitTests.cs. V okně se zprávou, které se zobrazí, vyberte Ano, abyste přejmenovali všechny odkazy UnitTest1 na WatchFunctionUnitTests.
V okně Průzkumník řešení klikněte v projektu WatchFunctionsTests pravým tlačítkem myši na Závislosti a pak vyberte Přidat odkaz na projekt.
V okně Správce odkazů vyberte projekt WatchPortalFunction a pak zvolte OK.
Přidání testů jednotek pro funkci WatchInfo
Teď můžete přidat testy jednotek do projektu testů. Ve scénáři prodeje luxusních hodinek chcete zajistit, aby funkce WatchInfo vždy vrátila odpověď OK, když je v řetězci dotazu požadavku uveden model, a odpověď Bad (Chyba), když je řetězec dotazu prázdný nebo neobsahuje parametr model
.
Chcete-li toto chování ověřit, přidáte do watchFunctionsTests dvojici testů faktů.
Pokud chcete v okně Průzkumník řešení zobrazit WatchPortalFunction v okně kódu, poklikejte na soubor WatchFunctionUnitTests.cs.
Do seznamu na začátku souboru přidejte následující direktivy
using
.using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Internal; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Logging.Abstractions;
Změňte název metody Test1 na TestWatchFunctionSuccess.
V těle metody TestWatchFunctionSuccess přidejte následující kód. Tento příkaz vytvoří napodobeninu kontextu HTTP a požadavek HTTP. Součástí tohoto požadavku je řetězec dotazu, který obsahuje parametr
model
nastavený naabc
.var queryStringValue = "abc"; var request = new DefaultHttpRequest(new DefaultHttpContext()) { Query = new QueryCollection ( new System.Collections.Generic.Dictionary<string, StringValues>() { { "model", queryStringValue } } ) };
Do metody přidejte následující příkaz. Tento příkaz vytvoří fiktivní protokolovač.
var logger = NullLoggerFactory.Instance.CreateLogger("Null Logger");
Do metody přidejte následující kód. Tyto příkazy vyvolají funkci WatchInfo a předají fiktivní požadavek a protokolovač jako parametry.
var response = WatchPortalFunction.WatchInfo.Run(request, logger); response.Wait();
Do metody přidejte následující kód. Tento kód zkontroluje správnost odpovědi funkce. V tomto případě by funkce měla vrátit odpověď OK obsahující očekávaná data v těle.
// Check that the response is an "OK" response Assert.IsAssignableFrom<OkObjectResult>(response.Result); // Check that the contents of the response are the expected contents var result = (OkObjectResult)response.Result; dynamic watchinfo = new { Manufacturer = "abc", CaseType = "Solid", Bezel = "Titanium", Dial = "Roman", CaseFinish = "Silver", Jewels = 15 }; string watchInfo = $"Watch Details: {watchinfo.Manufacturer}, {watchinfo.CaseType}, {watchinfo.Bezel}, {watchinfo.Dial}, {watchinfo.CaseFinish}, {watchinfo.Jewels}"; Assert.Equal(watchInfo, result.Value);
Úplná metoda by měla vypadat takto.
[Fact] public void TestWatchFunctionSuccess() { var queryStringValue = "abc"; var request = new DefaultHttpRequest(new DefaultHttpContext()) { Query = new QueryCollection ( new System.Collections.Generic.Dictionary<string, StringValues>() { { "model", queryStringValue } } ) }; var logger = NullLoggerFactory.Instance.CreateLogger("Null Logger"); var response = WatchPortalFunction.WatchInfo.Run(request, logger); response.Wait(); // Check that the response is an "OK" response Assert.IsAssignableFrom<OkObjectResult>(response.Result); // Check that the contents of the response are the expected contents var result = (OkObjectResult)response.Result; dynamic watchinfo = new { Manufacturer = "abc", CaseType = "Solid", Bezel = "Titanium", Dial = "Roman", CaseFinish = "Silver", Jewels = 15 }; string watchInfo = $"Watch Details: {watchinfo.Manufacturer}, {watchinfo.CaseType}, {watchinfo.Bezel}, {watchinfo.Dial}, {watchinfo.CaseFinish}, {watchinfo.Jewels}"; Assert.Equal(watchInfo, result.Value); }
Přidejte další dvě metody nazvané TestWatchFunctionFailureNoQueryString a TestWatchFunctionFailureNoModel. Metoda TestWatchFunctionFailureNoQueryString ověřuje, jestli funkce WatchInfo selže bez výpadku, pokud není zadán řetězec dotazu. Metoda TestWatchFunctionFailureNoModel vyhledává stejnou chybu, pokud je do této funkce předán řetězec dotazu, který neobsahuje parametr modelu.
[Fact] public void TestWatchFunctionFailureNoQueryString() { var request = new DefaultHttpRequest(new DefaultHttpContext()); var logger = NullLoggerFactory.Instance.CreateLogger("Null Logger"); var response = WatchPortalFunction.WatchInfo.Run(request, logger); response.Wait(); // Check that the response is an "Bad" response Assert.IsAssignableFrom<BadRequestObjectResult>(response.Result); // Check that the contents of the response are the expected contents var result = (BadRequestObjectResult)response.Result; Assert.Equal("Please provide a watch model in the query string", result.Value); } [Fact] public void TestWatchFunctionFailureNoModel() { var queryStringValue = "abc"; var request = new DefaultHttpRequest(new DefaultHttpContext()) { Query = new QueryCollection ( new System.Collections.Generic.Dictionary<string, StringValues>() { { "not-model", queryStringValue } } ) }; var logger = NullLoggerFactory.Instance.CreateLogger("Null Logger"); var response = WatchPortalFunction.WatchInfo.Run(request, logger); response.Wait(); // Check that the response is an "Bad" response Assert.IsAssignableFrom<BadRequestObjectResult>(response.Result); // Check that the contents of the response are the expected contents var result = (BadRequestObjectResult)response.Result; Assert.Equal("Please provide a watch model in the query string", result.Value); }
Spuštění testů
V horním řádku nabídek v části Test vyberte Spustit všechny testy.
V okně Průzkumníka testů by se měly úspěšně dokončit všechny tři testy.
V okně Průzkumníka řešení poklikejte v projektu WatchPortalFunction na WatchInfo.cs, abyste tento soubor zobrazili v editoru kódu.
Vyhledejte následující kód.
// Retrieve the model id from the query string string model = req.Query["model"];
Změňte příkaz, který nastavuje proměnnou
model
, následujícím způsobem. Tato změna simuluje, aby vývojář udělal chybu v kódu.string model = req.Query["modelll"];
V horním řádku nabídek v části Test vyberte Spustit všechny testy. Tentokrát by test TestWatchFunctionSuccess měl být neúspěšný. K této chybě dochází, protože funkce WatchInfo nenajde parametr pojmenovaný
modelll
v řetězci dotazu, takže funkce vrátí chybnou odpověď.
V této lekci jste viděli, jak vytvořit projekt testování jednotek a implementovat testy jednotek pro funkci Azure Functions.