Izolowanie testowanego kodu za pomocą struktury Microsoft Fakes

Pomoc programu Microsoft Fakes wyizolować kodu podczas testowania, zastępując innych części aplikacji za pomocą procedury wejścia lub Ustawienia.Są to małe fragmenty kodu, będące pod kontrolą Twoich testów.Izolując kod do testowania, wiesz, że jeśli test wypadnie niepomyślnie, przyczyna leży tam, a nie w żadnym innym miejscu.Podkładki i wycinki pozwalają na testowanie kodu, nawet jeśli pozostałe części aplikacji jeszcze nie działają.

Podróbki występują w dwóch wersjach:

  • Element skrótowa zamienia klasę małych zastępczych, który implementuje ten interfejs.Aby użyć wycinków, należy tak zaprojektować aplikację, aby każdy składnik zależał jedynie od interfejsów, a nie od innych składników.(Przez „składnik” rozumie się klasy lub grupy klas, które są zaprojektowane i aktualizowane łącznie i zwykle są zawarte w zestawie).

  • Element podkładka modyfikuje skompilowany kod aplikacji w czasie wykonywania, a nie wywołania określonej metody wykonywania kodu podkładka, który udostępnia test.Podkładki można wykorzystywać do zastępowania wywołań do zespołów, których nie można modyfikować, takich jak zestawy .NET.

Inne składniki zastąpić fakes

Wymagania

  • Visual Studio Ultimate lub Premium

Wybór między typami podkładek i wycinków

Projekt Visual Studio zazwyczaj zostanie zakwalifikowany jako składnik, ponieważ klasy te są opracowywane i aktualizowane równocześnie.Można rozważyć użycie wycinków i podkładek do wywołań, które dany projekt kieruje w stronę innych projektów w rozwiązaniu, lub w stronę innych zestawów, do których projekt się odnosi.

Jako ogólnej wskazówki należy użyć fragmentów dla wywołań w ramach rozwiązania Visual Studio i podkładek dla wywołań do innych zestawów, do których istnieje odwołanie.Dzieje się tak, ponieważ wewnątrz własnego rozwiązania warto ćwiczyć rozdzielanie par składników przez definiowanie interfejsów w sposób wymagany przez wycinkowanie.Zespoły zewnętrzne, takie jak System.dll, zazwyczaj nie są wyposażone w osobne definicje interfejsu, więc zamiast tego należy używać podkładek.

Inne zagadnienia to:

Wydajność. Podkładki działają wolniej, ponieważ przepisują kod w czasie wykonywania.Wycinki kodu nie mają dodatkowego obciążenia i są równie szybkie, jak metody wirtualne.

Metody statyczne zapieczętowanych typów. Możesz używać wycinków tylko do implementacji interfejsów.Tym samym typy wycinka nie mogą być stosowane dla metod statycznych, metod niewirtualnych, zaplombowanych metod wirtualnych, metod w zaplombowanych typach itd.

Typy wewnętrznego. Można użyć zarówno procedury wejścia i ustawienia z typów wewnętrznych, które są udostępniane za pomocą atrybutu zestawu InternalsVisibleToAttribute.

Prywatny metody. Podkładki zastępują wywołania metod prywatnych, jeśli widoczne są wszystkie typy podpisów metody.Wycinki kodu mogą zastąpić jedynie metody widoczne.

Interfejsy i metody abstrakcyjne. Wycinki kodu zapewniają implementacje interfejsów i metody abstrakcyjne, które mogą służyć do testowania.Podkładki nie mogą instrumentować interfejsów i metod abstrakcyjnych, ponieważ nie zawierają treści metody.

Zasadniczo zaleca się używanie typów wycinków w celu odseparowania od zależności w ramach własnej bazy kodów.Można to zrobić, ukrywając składniki za interfejsami.Typy podkładek można wykorzystywać do izolowania od składników innych firm, które nie mają sprawdzalnego API.

Wprowadzenie do wycinków

(Aby uzyskać bardziej szczegółowe informacje, zobacz Stosowanie wycinków kodu do izolowania od siebie poszczególnych części aplikacji w celu przeprowadzania testów jednostkowych.)

  1. Interfejsy wsunięć

    Aby użyć wycinków, musisz napisać kod, który chcesz przetestować w taki sposób, aby nie wymieniał wprost klas w innych składnikach Twojej aplikacji.Przez „składnik” rozumie się klasę lub grupę klas, które są opracowane i aktualizowane łącznie i zwykle są zawarte w jednym projekcie Visual Studio.Zmienne i parametry powinny być zdeklarowane przy użyciu interfejsów, a wystąpienia innych składników powinny zostać przekazane lub utworzone za pomocą fabryki.Jeśli na przykład StockFeed jest klasą w innym składniku aplikacji, zostałoby to uznane za nieprawidłowe:

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

    Zamiast tego zdefiniuj interfejs, który może być implementowany przez inny składnik, a także przez wycinek dla celów testowych:

    public int GetContosoPrice(IStockFeed feed)
    { return feed.GetSharePrice("COOO"); }
    
    Public Function GetContosoPrice(feed As IStockFeed) As Integer
     Return feed.GetSharePrice("COOO")
    End Function
    
  2. Dodawanie podrobionych zestawów

    1. W oknie Eksploratora rozwiązań rozwiń listę odwołań projektu testowego.Jeśli pracujesz w języku Visual Basic, należy wybrać Pokaż wszystkie pliki aby wyświetlić listę odwołania.

    2. Wybierz odwołanie do zestawu, w którym zdefiniowano interfejs (na przykład IStockFeed).W menu skrótów tego odwołania, wybierz polecenie dodać zestawu Fakes.

    3. Ponowne kompilowanie rozwiązania.

  3. W testach należy skonstruować wystąpienia wycinka i podać kod dla jego 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
    

    Specjalne urządzenie magiczny w tym miejscu jest klasą StubIStockFeed.Dla każdego interfejsu w zestawie, do którego istnieje odwołanie, mechanizm Microsoft Fakes generuje klasę zastępczą.Nazwa Klasa zastępcza jest pochodny od nazwy interfejsu z "Fakes.Stub" jako prefiksu i dołączany nazwy typu parametru.

    Wycinki kodu są generowane także dla metod pobierających i ustawiających właściwości, dla zdarzeń i metod ogólnych.Aby uzyskać więcej informacji, zobacz Stosowanie wycinków kodu do izolowania od siebie poszczególnych części aplikacji w celu przeprowadzania testów jednostkowych.

Wprowadzenie do podkładek

(Aby uzyskać bardziej szczegółowe informacje, zobacz Stosowanie podkładek do izolowania aplikacji od innych zestawów w celu przeprowadzania testów jednostkowych.)

Załóżmy, że składnik zawiera wywołania DateTime.Now:

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

Podczas testowania, chce podkładka Now Właściwości, ponieważ wersja rzeczywistych inconveniently zwraca różne wartości w każdym wywołaniu.

Aby użyć podkładek, nie trzeba modyfikować kodu aplikacji ani pisać go w określony sposób.

  1. Dodawanie podrobionych zestawów

    W oknie Eksplorator rozwiązań otwórz odniesienia projektu testu jednostkowego i wybierz odwołanie do zestawu zawierającego metodę, którą chcesz substytuować.W tym przykładzie DateTime Klasa znajduje się w System.dll.Aby wyświetlić odwołań w projekcie języka Visual Basic, wybierz polecenie Pokaż wszystkie pliki.

    Wybierz dodać zestawu Fakes.

  2. Wstaw podkładkę w 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
    

    Nazwy klasy podkładka składają się prefiksu Fakes.Shim do oryginalnej nazwy typu.Nazwy parametrów są dołączane do nazwy metody.(Nie trzeba dodać jakiegokolwiek odniesienia projektu do System.Fakes)

W poprzednim przykładzie podkładka jest wykorzystana do metody statycznej.Aby użyć podkładka metody wystąpienia, zapisu AllInstances między nazwą typu i nazwa metody:

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

Nie masz do wstawienia jakiegokolwiek odniesienia do System.IO.Fakes: została utworzona przez funkcję podkładka procesu tworzenia.

Można również utworzyć podkładki dla konkretnych wystąpień, konstruktorów i właściwości.Aby uzyskać więcej informacji, zobacz Stosowanie podkładek do izolowania aplikacji od innych zestawów w celu przeprowadzania testów jednostkowych.

W tej sekcji

Stosowanie wycinków kodu do izolowania od siebie poszczególnych części aplikacji w celu przeprowadzania testów jednostkowych

Stosowanie podkładek do izolowania aplikacji od innych zestawów w celu przeprowadzania testów jednostkowych

Konwencje dotyczące generowania, kompilowania i nazywania w Microsoft Fakes