Share via


Unit test per metodi generici

È possibile generare unit test per metodi generici procedendo esattamente come per altri metodi, secondo la descrizione in Procedura: creare ed eseguire uno unit testd .Nelle sezioni seguenti vengono fornite informazioni sulla creazione di unit test per i metodi generici, con esempi.

Digitare vincoli di argomenti e tipi

Quando Visual Studio genera uno unit test per una classe generica, ad esempio MyList<T>, vengono generati due metodi: un file di supporto generico e un metodo di test.Se MyList<T> presenta uno o più vincoli per tipo, l'argomento relativo dovrà soddisfare tutti i vincoli di tale tipo.Per assicurarsi che il codice generico in fase di test funzioni come previsto per tutti gli input consentiti, il metodo di test chiama il metodo di supporto generico insieme a tutti i vincoli che si desidera testare.

Esempi

Negli esempi seguenti sono illustrati gli unit test di tipo generico:

  • Modifica del codice di test generato.Il presente esempio ha due sezioni, Codice di test generato e Codice di test modificato.Mostra come trasformare un codice del test non elaborato generato da un metodo generico in un metodo di test utile.

  • Utilizzo di un vincolo di tipo.Il seguente esempio mostra uno unit test per un metodo generico che utilizzi un di vincolo del tipo.Il vincolo di tipo non viene soddisfatto.

ms243401.collapse_all(it-it,VS.110).gifEsempio 1: Modifica di codice di Test generato

Il codice di test in tale sezione verifica un metodo di codice sotto test, denominato SizeOfLinkedList().Questo metodo restituisce un numero intero che specifica il numero di nodi nell'elenco collegato.

Il primo esempio di codice, nella sezione Codice di test generato, mostra il codice di test senza modifiche, così come è stato generato da Visual Studio Premium o Visual Studio Ultimate.Il secondo esempio, nella sezione Codice di test modificato, mostra come far sì che venga testato il funzionamento del metodo SizeOfLinkedList per due tipi di dati diversi, int e char.

Tale codice illustra due metodi:

  • un metodo di supporto di test, SizeOfLinkedListTestHelper<T>().Per impostazione predefinita, il nome di un metodo di supporto di test conterrà "TestHelper".

  • un metodo di test, SizeOfLinkedListTest().Ogni metodo di test è contrassegnato con l'attributo TestMethod.

ms243401.collapse_all(it-it,VS.110).gifCodice di test generato

Il codice di test seguente è stato generato dal metodo SizeOfLinkedList().Poiché questo è il test generato e non modificato, deve essere cambiato per poter testare correttamente il metodo SizeOfLinkedList.

public void SizeOfLinkedListTestHelper<T>()
{
    T val = default(T); // TODO: Initialize to an appropriate value
    MyLinkedList<T> target = new MyLinkedList<T>(val); // TODO: Initialize to an appropriate value
    int expected = 0; // TODO: Initialize to an appropriate value
    int actual;
    actual = target.SizeOfLinkedList();
    Assert.AreEqual(expected, actual);
    Assert.Inconclusive("Verify the correctness of this test method.");
}

[TestMethod()]
public void SizeOfLinkedListTest()
{
   SizeOfLinkedListTestHelper<GenericParameterHelper>();
}

Nel codice precedente, il parametro di tipo generico è GenericParameterHelper.Mentre è possibile modificarlo per fornire specifici tipi di dati, come nell'esempio seguente, è possibile eseguire il test senza modificare tale istruzione.

ms243401.collapse_all(it-it,VS.110).gifCodice di test modificato

Nel codice seguente, il metodo di test e il metodo di supporto di test sono stati modificati per far sì che testino correttamente il metodo SizeOfLinkedList()di codice sotto test.

ms243401.collapse_all(it-it,VS.110).gifMetodo di supporto di test

Il metodo di supporto di test esegue i passaggi seguenti, che corrispondono alle righe nel codice indicato dal passaggio 1 al passaggio 5.

  1. Creare un elenco generico collegato .

  2. Aggiungere quattro nodi all'elenco collegato.I tipi di dati contenuti di tali nodi sono ignoti.

  3. Assegnare la dimensione prevista dell'elenco collegato alla variabile expected.

  4. Calcolare la dimensione effettiva dell'elenco collegato e assegnarla alla variabile actual.

  5. Confrontare actual con expected in un'istruzione Assert.Se il risultato effettivo non è uguale a quello previsto, il test non riesce.

ms243401.collapse_all(it-it,VS.110).gifMetodo di test

Il metodo di test viene compilato nel codice chiamato, quando si esegue il test detto SizeOfLinkedListTest.In questo modo vengono eseguiti i passaggi seguenti, che corrispondono alle righe nel codice indicato dal passaggio 6 al 7.

  1. Specificare <int> quando si chiama il metodo di supporto di test, per verificare che il test funzioni per le variabili integer.

  2. Specificare <char> quando si chiama il metodo di supporto di test, per verificare che il test funzioni per le variabili char.

public void SizeOfLinkedListTestHelper<T>()
{
    T val = default(T); 
    MyLinkedList<T> target = new MyLinkedList<T>(val); // step 1
    for (int i = 0; i < 4; i++) // step 2
    {
        MyLinkedList<T> newNode = new MyLinkedList<T>(val);
        target.Append(newNode);
    }
    int expected = 5; // step 3
    int actual;
    actual = target.SizeOfLinkedList(); // step 4
    Assert.AreEqual(expected, actual); // step 5
}

[TestMethod()]
public void SizeOfLinkedListTest() 
{
    SizeOfLinkedListTestHelper<int>();  // step 6
    SizeOfLinkedListTestHelper<char>(); // step 7
}

[!NOTA]

Ogni volta che viene eseguito il test SizeOfLinkedListTest, il relativo metodo TestHelper viene chiamato due volte.L'istruzione dell'asserzione deve valutare la verità perchè il test passi.Se il test ha esito negativo, potrebbe non essere chiaro se ciò sia dovuto alla chiamata che ha specificato <int> o alla chiamata che ha specificato <char>.Per trovare la risposta è possibile esaminare lo stack di chiamate, oppure impostare dei punti di interruzione nel metodo di test e quindi eseguire il debug durante l'esecuzione del test.Per ulteriori informazioni, vedere Procedura: eseguire il debug durante l'esecuzione di un test in una soluzione ASP.NET.

ms243401.collapse_all(it-it,VS.110).gifEsempio 2: Utilizzo di un vincolo tipo

Il presente esempio mostra uno unit test per un metodo generico, che utilizza un vincolo di tipo che non viene soddisfatto.La prima sezione mostra del codice dal progetto di codice sotto test.Il vincolo di tipo è evidenziato.

La seconda sezione mostra del codice dal progetto di test.

ms243401.collapse_all(it-it,VS.110).gifProgetto di codice sotto test

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace ClassLibrary2
{
    public class Employee
    {
        public Employee(string s, int i)
        {
        }
    }

    public class GenericList<T> where T : Employee
    {
        private class Node
        {
            private T data;
            public T Data
            {
                get { return data; }
                set { data = value; }
            }
        }
    }
}

ms243401.collapse_all(it-it,VS.110).gifProgetto test

Come per tutti gli unit test appena generati, è necessario aggiungervi istruzioni di asserzione non inclusive perché restituisca risultati utili.Non verranno aggiunte al metodo contrassegnato con l'attributo TestMethod, ma al metodo "TestHelper" che per questo test è denominato DataTestHelper<T>().

In questo esempio, il parametro di tipo generico T ha il vincolo where T : Employee.Tale vincolo non viene soddisfatto nel metodo di test.Perciò, il metodo DataTest() contiene un'istruzione asserzione che avvisa della necessità di fornire il vincolo di tipo inserito in T.Il messaggio di tale istruzione Assert è il seguente: ("No appropriate type parameter is found to satisfies the type constraint(s) of T. " + "Please call DataTestHelper<T>() with appropriate type parameters.");

In altre parole, quando si chiama il metodo DataTestHelper<T>() dal metodo di test DataTest(), è necessario passare un parametro di tipo Employee o una classe derivata da Employee.

using ClassLibrary2;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestProject1

{
    [TestClass()]
    public class GenericList_NodeTest
    {
    
        public void DataTestHelper<T>()
            where T : Employee
        {
            GenericList_Shadow<T>.Node target = new GenericList_Shadow<T>.Node(); // TODO: Initialize to an appropriate value
            T expected = default(T); // TODO: Initialize to an appropriate value
            T actual;
            target.Data = expected;
            actual = target.Data;
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        [TestMethod()]
        public void DataTest()
        {
            Assert.Inconclusive("No appropriate type parameter is found to satisfies the type constraint(s) of T. " +
            "Please call DataTestHelper<T>() with appropriate type parameters.");
        }
    }
}

Vedere anche

Concetti

Verifica del codice tramite unit test

Altre risorse

Composizione di uno unit test