Övning – Enhetstesta en Azure-funktion

Slutförd

Enhetstestning är en fundamental aspekt inom agil metodik. Visual Studio ger tillgång till en mall för projekttestning. Använd den här mallen för att skapa enhetstesterna för dina program. Du kan använda samma teknik för att testa Azure Functions.

I scenariot med onlinewebbplatsen för lyxklockan har utvecklingsteamet en princip för att uppnå minst 80 % kodtäckning i enhetstestning. Du vill implementera samma princip för Azure Functions.

Här ser du hur du använder xUnit testramverket med Visual Studio för att testa Azure Functions.

Skapa ett projekt för enhetstestning

Det första steget är att skapa ett projekt som innehåller dina enhetstester och lägga till det i lösningen som innehåller din Azure-funktionsapp. Följ stegen nedan för att skapa ett projekt för enhetstestning som ska testa funktionen WatchInfo.

  1. I Visual Studio, i fönstret Solution Explorer, högerklickar du på WatchPortalFunction-lösningen. Välj Add (Lägg till) och välj sedan New Project (Nytt projekt).

    Skärmbild av Solution Explorer med kommandot för att lägga till ett nytt projekt i lösningen.

  2. I fönstret Lägg till ett nytt projekt rullar du nedåt, väljer mallen xUnit Test ProjectC#+ och väljer sedan Nästa.

    Skärmbild av fönstret Lägg till nytt projekt. Mallen xUnit Test Project är markerad.

  3. Fönstret Configure your new project (Konfigurera ditt nya projekt) visas. I fältet Project name (Projektnamn) anger du WatchFunctionsTests. Förutom fältet Plats väljer du bläddra-ikonen och väljer sedan mappen WatchPortalFunction .

  4. Välj Nästa. Fönstret Ytterligare information visas.

  5. Under Målramverk. acceptera standardvärdet för .NET 6.0 (långsiktigt stöd).

  6. Välj Skapa.

  7. När projektet har lagts till högerklickar du på projektet WatchFunctionTests i Solution Explorer-fönstret och väljer sedan Hantera NuGet-paket.

  8. I fönstret NuGet: WatchFunctionTests väljer du fliken Bläddra. I sökrutananger du Microsoft.AspNetCore.Mvc. Välj Microsoft.AspNetCore.Mvc-paketet, och välj sedan Install (Installera).

    Skärmbild av fönstret NuGet Package Manager. Användaren installerar Microsoft.AspNetCore.Mvc-paketet.

    Kommentar

    Testprojektet skapar en HTTP-testmiljö. De klasser som krävs för att göra detta finns i Microsoft.AspNetCore.Mvc-paketet.

  9. Vänta medan paketet är installerat. Om meddelanderutan Preview Changes (Förhandsgranska ändringar) visas väljer du OK. I meddelanderutan License Acceptance (Licensgodkännande) väljer du I Accept (Jag acccepterar).

  10. När paketet har lagts till högerklickar du på filen UnitTest1.cs i solution explorer-fönstret under projektet WatchFunctionsTests och väljer byt namn. Ändra namnet på filen till WatchFunctionUnitTests.cs. I meddelanderutan som visas byter du namn på alla referenser för UnitTest1 till WatchFunctionUnitTests genom att välja Yes (Ja).

  11. Högerklicka på Beroenden under projektet WatchFunctionsTests i Solution Explorer och välj sedan Lägg till projektreferens.

  12. I fönstret Reference Manager (Referenshanteraren) väljer du WatchPortalFunction-projektet. Välj sedan OK.

Lägga till enhetstester för funktionen WatchInfo

Nu kan du lägga till enhetstester i testprojektet. I scenariot med lyxklockor vill du att funktionen WatchInfo alltid ska returnera ett jakande svar när en modell anges i frågesträngen för en begäran, och ett nekande svar om frågesträngen är tom eller inte innehåller model-parametern.

För att verifiera det här beteendet lägger du till ett par faktatester i WatchFunctionsTests.

  1. Om du vill visa WatchPortalFunction i kodfönstret i Solution Explorer dubbelklickar du på filen WatchFunctionUnitTests.cs.

  2. Längst upp i filen lägger du till följande using-direktiv i listan.

    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Http.Internal;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Primitives;
    using Microsoft.Extensions.Logging.Abstractions;
    
  3. Ändra namnet på Test1-metoden till TestWatchFunctionSuccess.

  4. Lägg till följande kod i själva TestWatchFunctionSuccess-metoden. Den här instruktionen skapar en HTTP-testkontext och en HTTP-testbegäran. Begäran innehåller en frågesträng som innehåller parametern model, som tilldelas värdet abc.

    var queryStringValue = "abc";
    var request = new DefaultHttpRequest(new DefaultHttpContext())
    {
        Query = new QueryCollection
        (
            new System.Collections.Generic.Dictionary<string, StringValues>()
            {
                { "model", queryStringValue }
            }
        )
    };
    
  5. Lägg till följande instruktion i metoden. Den här instruktionen skapar en dummy-loggare.

    var logger = NullLoggerFactory.Instance.CreateLogger("Null Logger");
    
  6. Lägg till följande kod i metoden. Dessa instruktioner anropar funktionen WatchInfo och anger dummy-begäran och dummy-loggaren som parametrar.

    var response = WatchPortalFunction.WatchInfo.Run(request, logger);
    response.Wait();
    
  7. Lägg till följande kod i metoden. Den här koden kontrollerar att svaret från funktionen är korrekt. I det här fallet ska funktionen returnera ett OK-svar som innehåller förväntade data i brödtexten.

    // 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);
    

    Den fullständiga metoden bör se ut så här.

    [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);
    }
    
  8. Lägg till ytterligare två metoder med namnen TestWatchFunctionFailureNoQueryString och TestWatchFunctionFailureNoModel. TestWatchFunctionFailureNoQueryString verifierar att WatchInfo-funktionen avslutas korrekt om den inte mottar någon frågesträng. TestWatchFunctionFailureNoModel söker efter samma fel om funktionen mottar en frågesträng som inte innehåller en modellparameter.

    [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);
    }
    

Kör testerna

  1. På den översta menyraden går du till Test och väljer Kör alla tester.

    Skärmbild av testmenyn i Visual Studio. Användaren har valt Kör –> Alla tester.

  2. Alla tre tester bör slutföras korrekt i Test Explorer.

    Skärmbild av fönstret Team Explorer. Alla tre testerna har körts.

  3. Gå till fönstret Solution Explorer. Under WatchPortalFunction-projektet dubbelklickar du på WatchInfo.cs så att filen visas i kodredigeraren.

  4. Leta upp följande kod.

    // Retrieve the model id from the query string
    string model = req.Query["model"];
    
  5. Ändra instruktionen som anger model-variabeln på följande sätt. Den här ändringen simulerar att utvecklaren gör ett misstag i koden.

    string model = req.Query["modelll"];
    
  6. På den översta menyraden går du till Test och väljer Kör alla tester. Den här gången bör testet TestWatchFunctionSuccess misslyckas. Det här felet beror på att funktionen WatchInfo inte hittar parametern med namnet modelll i frågesträngen, så funktionen returnerar ett felaktigt svar.

    Skärmbild av fönstret Team Explorer. TestWatchFunctionSuccess-testet misslyckades.

I den här lektionen såg du hur du skapar ett enhetstestprojekt och implementerar enhetstester för en Azure-funktion.