Sdílet prostřednictvím


Izolace testovaného kódu pomocí zástupného rozhraní Microsoft

Microsoft Fakes nápovědy izolovat kódu, testujete nahrazením jiných částí aplikace s kódy nebo Překryvné ovladače.Jedná se o malé části kódu, které jsou pod kontrolou testů.Díky izolaci testovacího kódu víte, že pokud se test nezdaří, příčina je zde a ne někde jinde.Zástupné procedury a překrytí také umožňují testování kódu, i když jiné části aplikace ještě nefungují.

Jsou dva typy napodobenin:

  • Objekt se zakázaným nahradí třída malé nahraďte text, který implementuje rozhraní stejné.Pro použití zástupných procedur je nutné navrhnout aplikaci tak, aby jednotlivé součásti závisely pouze na rozhraních a nikoli na ostatních součástech.(„Součást“ představuje třídu nebo skupinu tříd, které jsou navrženy a aktualizovány společně a obvykle obsaženy v sestavení.)

  • Objekt překrytí upravuje zkompilovaný kód vaší aplikace za běhu, takže namísto volání pro zadanou metodu běží překrytí kód, který poskytuje testování.Překrytí lze použít pro nahrazení volání do sestavení, která nelze upravit (např. sestavení .NET).

Fakes nahradit další součásti

Požadavky

  • Visual Studio Ultimate nebo Premium

Volba mezi zástupnou procedurou a překrytím

Obvykle byste měli považovat projekt sady Visual Studio za součást, protože vytváříte a aktualizujete tyto třídy současně.Měli byste zvážit použití zástupných procedur a překrytí pro volání, která projekt provádí do jiných projektů v rámci vašeho řešení nebo do jiných sestavení, na která projekt odkazuje.

Jako obecné vodítko použijte zástupné procedury pro volání v rámci řešení sady Visual Studio a překrytí použijte pro volání do jiných odkazovaných sestavení.Je to proto, že u vašeho vlastního řešení je vhodné oddělit součásti definováním rozhraní tak, jak vyžaduje vytváření zástupných procedur.Ale externí sestavení, jako například System.dll, nejsou obvykle vybavena samostatnými definicemi rozhraní, takže je nutné místo toho použít překrytí.

Ostatní úvahy:

Výkon. Překrytí pracují pomaleji, protože přepisují kód za běhu.Zástupné procedury nemají takové nároky na výkon a jsou stejně rychlé jako virtuální metody.

Statické metody zapečetěných typy. Zástupné procedury můžete použít pouze k implementaci rozhraní.Proto nelze použít typy zástupných procedur pro statické metody, nevirtuální metody, zapečetěné virtuální metody, metody v zapečetěných typech atd.

Vnitřní typy. Kódy a Překryvné ovladače lze použít s vnitřní typy, které jsou zpřístupněny pomocí atributu sestavení InternalsVisibleToAttribute.

Privátní metody. Překrytí mohou nahradit volání do soukromých metod, pokud jsou viditelné všechny typy v podpisu metody.Zástupné procedury mohou nahradit pouze viditelné metody.

Rozhraní a abstraktní metody. Zástupné procedury poskytují implementace rozhraní a abstraktní metody, které lze použít při testování.Překrytí nemohou využít rozhraní a abstraktní metody, protože nedisponují těly metody.

Obecně doporučujeme používat typy zástupných procedur k izolaci od závislostí v rámci vašeho základu kódu.To lze provést skrytím součástí za rozhraní.Typy překrytí lze použít k izolaci od součástí třetích stran, které neposkytují testovatelné rozhraní API.

Začínáme se zástupnými procedurami

(Další podrobný popis naleznete v tématu Vzájemná izolace částí aplikace pomocí zástupných procedury za účelem testování částí.)

  1. Vložení rozhraní

    Chcete-li použít zástupné procedury, musíte kód, který chcete otestovat, napsat takovým způsobem, aby explicitně nezmiňoval třídy v jiné součásti aplikace.„Součást“ představuje třídu nebo třídy, které jsou vyvíjeny a aktualizovány společně a obvykle jsou obsaženy v jednom projektu sady Visual Studio.Proměnné a parametry by měly být deklarovány pomocí rozhraní a instance ostatních součástí by měly být předány nebo vytvořeny pomocí továrny.Například pokud je součást StockFeed třídou v jiné součásti aplikace, pak toto bude považováno za chybné:

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

    Namísto toho definujte rozhraní, které lze implementovat jinou součástí a které může být také implementováno pomocí zástupné procedury pro testovací účely:

    public int GetContosoPrice(IStockFeed feed)
    { return feed.GetSharePrice("COOO"); }
    
    Public Function GetContosoPrice(feed As IStockFeed) As Integer
     Return feed.GetSharePrice("COOO")
    End Function
    
  2. Přidání napodobenin sestavení

    1. V Průzkumníku řešení rozbalte seznam odkazů testového projektu.Pokud pracujete v jazyce Visual Basic, je třeba zvolit Zobrazit všechny soubory Chcete-li zobrazit seznam odkazů.

    2. Vyberte odkaz na sestavení, ve kterém je definováno rozhraní (například IStockFeed).V místní nabídce odkazu, zvolte Přidat sestavení Fakes.

    3. Znovu sestavte řešení.

  3. Ve vašich testech vytvořte instance zástupné procedury a zadejte kód pro jeho metody:

    [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
    

    Zvláštní část magické číslo zde je třída StubIStockFeed.Pro každé rozhraní v odkazovaném sestavení generuje mechanismus rozhraní Microsoft Fakes zástupnou třídu.Název třídy se zakázaným je odvozené od názvu v rozhraní s "Fakes.Stub" jako předpony a připojenou názvy parametrů typu.

    Zástupné procedury jsou také generovány pro mechanismy získání a nastavení vlastností, pro události a pro obecné metody.Další informace naleznete v tématu Vzájemná izolace částí aplikace pomocí zástupných procedury za účelem testování částí.

Začínáme s překrytími

(Další podrobný popis naleznete v tématu Izolace aplikace od ostatních sestavení pomocí překrytí za účelem testování částí.)

Předpokládejme, že vaše komponenta obsahuje volání DateTime.Now:

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

Během testování, byste chtěli překrytí Now vlastnost, protože skutečnou verze inconveniently vrátí jinou hodnotu v každém volání.

Chcete-li použít překrytí, není nutné upravovat kód aplikace nebo jej zapsat určitým způsobem.

  1. Přidání napodobenin sestavení

    V Průzkumníku řešení otevřete odkazy projektu testování částí a vyberte odkaz na sestavení, které obsahuje metodu, kterou chcete simulovat.V tomto příkladu DateTime Třída je v System.dll.Chcete-li zobrazit odkazy v projektu Visual Basic, zvolte Zobrazit všechny soubory.

    Zvolte Přidat sestavení Fakes.

  2. Vložení překrytí do 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
    

    Názvy tříd překrytí jsou tvořený symbolů Fakes.Shim na původní název typu.Názvy parametrů jsou připojeny k názvu metody.(Nemusíte přidat projekt odkaz na System.Fakes)

Předchozí příklad používá překrytí pro statickou metodu.Chcete-li použít doplňkový kód pro metodu instance, napište AllInstances mezi název typu a názvu metody:

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

Nemusíte vložit odkaz na System.IO.Fakes: je vytvořen proces generování překrytí.

Můžete také vytvořit překrytí pro konkrétní instance, konstruktory a vlastnosti.Další informace naleznete v tématu Izolace aplikace od ostatních sestavení pomocí překrytí za účelem testování částí.

V tomto oddílu

Vzájemná izolace částí aplikace pomocí zástupných procedury za účelem testování částí

Izolace aplikace od ostatních sestavení pomocí překrytí za účelem testování částí

Vytváření, kompilace a konvence pojmenování kódu v Napodobeniny Microsoft