Isolamento del codice sottoposto a test con Microsoft Fakes

Le falsificazioni Microsoft consentono di isolare codice che si sta sostituendo altre parti dell'applicazione con gli stub o i pesi.Questi sono frammenti di codice che sono sotto il controllo dei test.Isolando il codice per il test, è noto che se il test ha esito negativo, la causa è presente e non altrove.Gli stub e i pesi anche consentono di testare il codice anche se altre parti dell'applicazione non lavorano su.

Le falsificazioni possono essere di due versioni:

  • stub sostituire la classe con un piccolo operativo che implementa la stessa interfaccia.Per utilizzare gli stub, è necessario progettare l'applicazione in modo che ogni componente dipende solo dalle interfacce e non in altri componenti.("Dal componente" tutto la classe o il gruppo di classi progettate e aggiornate raccolta e in genere sono contenute in un assembly.)

  • spessore modifica il codice compilato dell'applicazione in fase di esecuzione in modo che invece di effettuare la chiamata al metodo specificato, eseguire il codice dello shim che il test.I pesi possono essere utilizzati per sostituire le chiamate agli assembly che non è possibile modificare, tali assembly .NET.

Fakes sostituisce altri componenti

Requisiti

  • Visual Studio Ultimate

Scelta tra tipi stub e tipi shim

In genere, considerereste un progetto di Visual Studio essere un componente, perché si compila e si aggiornano tali classi contemporaneamente.Considerereste utilizzando gli stub e di fattori per le chiamate che il progetto vengono fatti in altri progetti nella soluzione, o ad altri assembly che i riferimenti al progetto.

Come una guida generale, gli stub di utilizzo per le chiamate all'interno della soluzione di Visual Studio e fattori per le chiamate ad altri assembly a cui si fa riferimento.Ciò è dovuto all'interno di una soluzione è consigliabile separare i componenti definendo le interfacce in modo che sradicare richiede.Ma gli assembly esterni quali System.dll in genere non vengono fornite le definizioni di interfaccia separate, pertanto è necessario utilizzare i pesi anziché.

Altre considerazioni sono:

Prestazioni. I pesi eseguono più lento perché riscriverlo il codice in fase di esecuzione.Gli stub non hanno questo sovraccarico delle prestazioni e sono velocemente quali metodi virtuali possono accedere.

Metodi statici, tipi sealed. È possibile utilizzare solo gli stub per implementare interfacce.Di conseguenza, i tipi stub non possono essere utilizzati per metodi statici, metodi non virtuali, metodi virtuali sealed, metodi con tipi sealed, e così via.

Tipi interni. Sia gli stub che i pesi possono essere utilizzati con i tipi interni che risultano accessibili tramite l'attributo InternalsVisibleToAttributedell'assembly.

Metodi privati. I pesi possono sostituire le chiamate ai metodi privati se tutti i tipi sulla firma del metodo sono visibili.Gli stub possono sostituire solo i metodi visibili.

Interfacce e metodi astratti. Gli stub forniscono le implementazioni di interfacce e metodi astratti che possono essere utilizzati nel test.I pesi non può instrumentare interfacce e metodi astratti, perché sono prive corpo del metodo.

È consigliabile, in generale, utilizzare i tipi stub per isolare dalle dipendenze nel codebase.Questo è possibile nascondendo i componenti dietro interfacce.I tipi shim possono essere utilizzati per isolare da componenti di terze parti che non forniscono un'API testabile.

Introduzione agli stub

  1. Inserire le interfacce

    Per utilizzare gli stub, è necessario scrivere il codice che si desidera testare in modo che non esplicitamente istanze delle classi in un'altra parte dell'applicazione."Dal componente" tutto la classe o le classi che vengono compilati insieme e aggiornati e in genere contenuto in un progetto di Visual Studio.Le variabili e i parametri devono essere dichiarati utilizzando le interfacce e le istanze di altri componenti devono essere passate in o essere creati utilizzando una factory.Ad esempio, se StockFeed è una classe in un'altra parte dell'applicazione, questo sia considerato non corretto:

    return (new StockFeed()).GetSharePrice("COOO"); // Bad

    Al contrario, definire un'interfaccia che può essere implementata dall'altro componente e che può essere implementata da uno stub per scopi di test:

    public int GetContosoPrice(IStockFeed feed)
    { return feed.GetSharePrice("COOO"); }
    
    Public Function GetContosoPrice(feed As IStockFeed) As Integer
     Return feed.GetSharePrice("COOO")
    End Function
    
  2. Aggiungere l'assembly di falsificazioni

    1. In Esplora soluzioni, espandere l'elenco del progetto di test.Se si utilizza Visual Basic, è necessario scegliere Mostra tutti i file per visualizzare l'elenco.

    2. Selezionare il riferimento all'assembly in cui l'interfaccia (ad esempio IStockFeed) è definita.Scegliere dal menu di scelta rapida del riferimento, scegliere Aggiungi assembly Fakes.

    3. Ricompilare la soluzione.

  3. Nei test, creare istanze con stub e immettere il codice per i relativi metodi:

    [TestClass]
    class TestStockAnalyzer
    {
        [TestMethod]
        public void TestContosoStockPrice()
        {
          // Arrange:
    
            // Create the fake stockFeed:
            IStockFeed stockFeed = 
                 new StockAnalysis.Fakes.StubIStockFeed() // Generated by Fakes.
                     {
                         // Define each method:
                         // Name is original name + parameter types:
                         GetSharePriceString = (company) => { return 1234; }
                     };
    
            // In the completed application, stockFeed would be a real one:
            var componentUnderTest = new StockAnalyzer(stockFeed);
    
          // Act:
            int actualValue = componentUnderTest.GetContosoPrice();
    
          // Assert:
            Assert.AreEqual(1234, actualValue);
        }
        ...
    }
    
    <TestClass()> _
    Class TestStockAnalyzer
    
        <TestMethod()> _
        Public Sub TestContosoStockPrice()
            ' Arrange:
            ' Create the fake stockFeed:
            Dim stockFeed As New StockAnalysis.Fakes.StubIStockFeed
            With stockFeed
                .GetSharePriceString = Function(company)
                                           Return 1234
                                       End Function
            End With
            ' In the completed application, stockFeed would be a real one:
            Dim componentUnderTest As New StockAnalyzer(stockFeed)
            ' Act:
            Dim actualValue As Integer = componentUnderTest.GetContosoPrice
            ' Assert:
            Assert.AreEqual(1234, actualValue)
        End Sub
    End Class
    

    La parte speciale di magia di seguito è riportata la classe StubIStockFeed.Per ogni interfaccia nell'assembly a cui si fa riferimento, il meccanismo di falsificazioni Microsoft genera una classe stub.Il nome della classe stub dei nomi dei tipi di parametro e come prefisso"Fakes.Stub"con, di un'interfaccia dal nome derivati aggiunti.

    Gli stub vengono generati per GET e funzioni insieme di proprietà, per gli eventi e per metodi generici.Per ulteriori informazioni, vedere Utilizzo di stub per isolare le parti dell'applicazione l'una dall'altra per gli unit test.

Introduzione ai pesi

Si supponga che il componente contenga chiamate a DateTime.Now:

// Code under test:
    public int GetTheCurrentYear()
    {
       return DateTime.Now.Year;
    }

Durante un test, si desidera rendere la proprietà di una zeppa di Now, poiché la versione reale inopportuno restituisce un valore diverso a ogni chiamata.

Per utilizzare i pesi, non è necessario modificare il codice dell'applicazione o scrivergli un modo specifico.

  1. Aggiungere l'assembly di falsificazioni

    In Esplora Risorse, aprire i riferimenti del progetto di unit test e selezionare il riferimento all'assembly che contiene il metodo da simulare.In questo esempio, la classe di DateTime è in System.dll.Per visualizzare i riferimenti in un progetto di Visual Basic., scegliere Mostra tutti i file.

    Scegliere Aggiungi assembly Fakes.

  2. Inserire un peso in uno ShimsContext

    [TestClass]
    public class TestClass1
    { 
            [TestMethod]
            public void TestCurrentYear()
            {
                int fixedYear = 2000;
    
                // Shims can be used only in a ShimsContext:
                using (ShimsContext.Create())
                {
                  // Arrange:
                    // Shim DateTime.Now to return a fixed date:
                    System.Fakes.ShimDateTime.NowGet = 
                    () =>
                    { return new DateTime(fixedYear, 1, 1); };
    
                    // Instantiate the component under test:
                    var componentUnderTest = new MyComponent();
    
                  // Act:
                    int year = componentUnderTest.GetTheCurrentYear();
    
                  // Assert: 
                    // This will always be true if the component is working:
                    Assert.AreEqual(fixedYear, year);
                }
            }
    }
    
    <TestClass()> _
    Public Class TestClass1
        <TestMethod()> _
        Public Sub TestCurrentYear()
            Using s = Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create()
                Dim fixedYear As Integer = 2000
                ' Arrange:
                ' Detour DateTime.Now to return a fixed date:
                System.Fakes.ShimDateTime.NowGet = _
                    Function() As DateTime
                        Return New DateTime(fixedYear, 1, 1)
                    End Function
    
                ' Instantiate the component under test:
                Dim componentUnderTest = New MyComponent()
                ' Act:
                Dim year As Integer = componentUnderTest.GetTheCurrentYear
                ' Assert: 
                ' This will always be true if the component is working:
                Assert.AreEqual(fixedYear, year)
            End Using
        End Sub
    End Class
    

    I nomi delle classi dello shim sono costituiti Fakes.Shim l'ambiguità del nome di tipo originale.I nomi dei parametri vengono aggiunti al nome del metodo.

Nell'esempio precedente viene utilizzato un peso per un metodo statico.Per utilizzare un peso per un metodo di istanza, scrivere AllInstances tra il nome del tipo e il nome del metodo:

System.IO.Fakes.ShimFile.AllInstances.ReadToEnd = ...

È inoltre possibile creare i pesi per le istanze specifiche, per i costruttori e per le proprietà.Per ulteriori informazioni, vedere Utilizzo di shim per isolare l'applicazione dagli altri assembly per gli unit test.

Contenuto della sezione

Utilizzo di stub per isolare le parti dell'applicazione l'una dall'altra per gli unit test

Utilizzo di shim per isolare l'applicazione dagli altri assembly per gli unit test

Generazione del codice, compilazione e convenzioni di denominazione in Microsoft Fakes