Esercizio: Eseguire lo unit test di una funzione di Azure

Completato

Il testing unità è una parte fondamentale della metodologia Agile. Visual Studio offre il modello di progetto di test. Usare questo modello per creare gli unit test per le applicazioni. È possibile applicare la stessa tecnica ai test per le funzioni di Azure.

Nello scenario del sito Web online per orologi di lusso, il team di sviluppo ha stabilito di ottenere almeno l'80% di copertura del codice per il testing unità. Si vogliono ora applicare questi criteri anche a Funzioni di Azure.

Viene qui illustrato come usare il framework di test xUnit con Visual Studio per testare Funzioni di Azure.

Creare un progetto di unit test

Il primo passaggio consiste nel creare un progetto che contiene gli unit test e nell’aggiungerlo alla soluzione che include l'app per le funzioni di Azure. Usare la procedura seguente per creare un progetto di unit test per testare la funzione WatchInfo.

  1. Nella finestra Esplora soluzioni di Visual Studio fare clic con il pulsante destro del mouse sulla soluzione WatchPortalFunction, scegliere Aggiungi e quindi scegliere Nuovo progetto.

    Screenshot di Esplora soluzioni con il comando per aggiungere un nuovo progetto a una soluzione.

  2. Nella finestra Aggiungi un nuovo progetto scorrere verso il basso, selezionare il modello Progetto xUnit TestC#+, quindi selezionare Avanti.

    Screenshot della finestra Aggiungi nuovo progetto. È selezionato il modello di progetto di test xUnit.

  3. Viene visualizzata la finestra Configura il nuovo progetto. Nel campo Nome del progetto immettere WatchFunctionsTests. A fianco del campo Posizione selezionare l'icona Sfoglia, quindi selezionare la cartella WatchPortalFunction.

  4. Selezionare Avanti. Viene visualizzata la finestra Informazioni aggiuntive.

  5. In Framework di destinazione. accettare il valore predefinito di .NET 6.0 (supporto a lungo termine).

  6. Seleziona Crea.

  7. Quando il progetto è stato aggiunto, fare clic con il pulsante destro del mouse sul progetto WatchFunctionTests nella finestra Esplora soluzioni e quindi selezionare Gestisci pacchetti NuGet.

  8. Nella finestra NuGet: WatchFunctionTests selezionare la scheda Sfoglia. Nella casella Ricerca immettere Microsoft.AspNetCore.Mvc. Selezionare i pacchetto Microsoft.AspNetCore.Mvc e quindi Installa.

    Screenshot della finestra Gestione pacchetti NuGet. L'utente installa il pacchetto Microsoft.AspNetCore.Mvc.

    Nota

    Il progetto di test creerà un ambiente HTTP fittizio. Le classi necessarie per questa operazione sono disponibili nel pacchetto Microsoft.AspNetCore.Mvc.

  9. Attendere il completamento dell'installazione del pacchetto. Se viene visualizzata la finestra di messaggio Anteprima modifiche, scegliere OK. Nella finestra di messaggio Accettazione della licenza selezionare Accetto.

  10. Dopo l'aggiunta del pacchetto, nella finestra Esplora soluzioni nel progetto WatchFunctionsTests fare clic con il pulsante destro del mouse sul file UnitTest1.cs e quindi selezionare Rinomina. Modificare il nome del file in WatchFunctionUnitTests.cs. Nella finestra di messaggio visualizzata scegliere per rinominare tutti i riferimenti di UnitTest1 in WatchFunctionUnitTests.

  11. Nella finestra Esplora soluzioni, nel progetto WatchFunctionsTests fare clic con il pulsante destro del mouse su Dipendenze, quindi selezionare Aggiungi riferimento al progetto.

  12. Nella finestra Gestione riferimenti selezionare il progetto WatchPortalFunction e quindi scegliere OK.

Aggiungere gli unit test per la funzione WatchInfo

È ora possibile aggiungere gli unit test al progetto di test. Nello scenario degli orologi di lusso si vuole essere certi che la funzione WatchInfo restituisca sempre una risposta OK quando viene fornito un modello nella stringa di query di una richiesta e una risposta Bad (Non valido) se la stringa di query è vuota o non contiene il model parametro.

Per verificare questo comportamento, si aggiunge una coppia di test Fact alla funzione WatchFunctionsTests.

  1. Nella finestra Esplora soluzioni fare doppio clic sul file WatchFunctionUnitTests.cs per visualizzare WatchPortalFunction nella finestra del codice.

  2. Aggiungere le direttive using seguenti all'inizio del file.

    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Http.Internal;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Primitives;
    using Microsoft.Extensions.Logging.Abstractions;
    
  3. Modificare il nome del metodo Test1 in TestWatchFunctionSuccess.

  4. Nel corpo del metodo TestWatchFunctionSuccess aggiungere il codice seguente. Questa istruzione crea un contesto HTTP e una richiesta HTTP fittizi. La richiesta include una stringa di query che include il parametro model, impostato su abc.

    var queryStringValue = "abc";
    var request = new DefaultHttpRequest(new DefaultHttpContext())
    {
        Query = new QueryCollection
        (
            new System.Collections.Generic.Dictionary<string, StringValues>()
            {
                { "model", queryStringValue }
            }
        )
    };
    
  5. Aggiungere l'istruzione seguente al metodo. Questa istruzione crea un logger fittizio.

    var logger = NullLoggerFactory.Instance.CreateLogger("Null Logger");
    
  6. Aggiungere il codice seguente al metodo . Queste istruzioni richiamano la funzione WatchInfo, passando la richiesta e il logger fittizi come parametri.

    var response = WatchPortalFunction.WatchInfo.Run(request, logger);
    response.Wait();
    
  7. Aggiungere il codice seguente al metodo . Questo codice verifica che la risposta dalla funzione sia corretta. In questo caso, la funzione dovrebbe restituire una risposta OK contenente i dati del corpo previsti.

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

    Il metodo completo dovrebbe essere simile al seguente.

    [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. Aggiungere altri due metodi denominati TestWatchFunctionFailureNoQueryString e TestWatchFunctionFailureNoModel. Il metodo TestWatchFunctionFailureNoQueryString verifica che la funzione WatchInfo venga interrotta normalmente se non riceve una stringa di query. Il metodo TestWatchFunctionFailureNoModel controlla la presenza dello stesso errore nel caso alla funzione venga passata una stringa di query che non contiene un parametro del modello.

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

Eseguire i test

  1. Nella barra dei menu superiore, in Test, selezionare Esegui tutti i test.

    Screenshot del menu Test in Visual Studio. L'utente ha selezionato Esegui -> Tutti i test.

  2. Nella finestra Esplora test tutti e tre i test dovrebbero essere completati correttamente.

    Screenshot della finestra Esplora test. Tutti e tre i test sono stati eseguiti correttamente.

  3. Nella finestra Esplora soluzioni, nel progetto WatchPortalFunction fare doppio clic su WatchInfo.cs per visualizzare il file nell'editor del codice.

  4. Trovare il codice seguente.

    // Retrieve the model id from the query string
    string model = req.Query["model"];
    
  5. Modificare l'istruzione che imposta la variabile model come indicato di seguito. Questa modifica simula un errore nel codice commesso dallo sviluppatore.

    string model = req.Query["modelll"];
    
  6. Nella barra dei menu superiore, in Test, selezionare Esegui tutti i test. Questa volta, il test TestWatchFunctionSuccess dovrebbe avere esito negativo. Questo errore si verifica perché la funzione WatchInfo non trova il parametro denominato modelll nella stringa di query, restituendo quindi una risposta Non corretto.

    Screenshot della finestra Esplora test. Il test TestWatchFunctionSuccess non è riuscito.

In questa unità si è visto come creare un progetto di unit test e implementare unit test per una funzione di Azure.