VS 2012 Fake DLLs für Tests (stubs und shims)


Aktuell hatte ich das “Vergnügen” mich mit der Unit Test Testbarkeit eines Projektes auseinander zu setzten. Da ich bisher nur mit Oberflächentests (Coded Ui) zu tun hatte, war eine Recherche angesagt und hier bin ich über diverse Mocking Frameworks wie z.B. “Moq” gestoßen die für Unit Tests zwingend benötigt werden. Außerdem gibt es ein neues Visual Studio CTP Update 2 hier steht jetzt ein eigenes Framework zum erstellen von Fake DLLs für die Visual Studio Versionen 2012 Premium und Ultimate zur Verfügung, diese Fake DLLs können ergänzend zu den Mocking Frameworks eingesetzt werden um Units Tests zu erstellen.

Im Folgenden will ich nur meinen kurzen Ausflug zum Erstellen eines Fake HttpContextes mit shims von MS Zeigen, was ich ziemlich Cool fand. Kommt bei mir aktuell leider nicht zum Einsatz, aber ein kurzes Beispiel schadet nicht.

Um eine Fake DLL zu erstellen muss die Referenz zum aktuellen Testprojekt hinzugefügt werden und dann mit der Rechten Maustaste auf der jeweiligen Referenz kann eine Fake Bibliothek angelegt werden.

image

Wenn man dann z.B. im Programm den Zugriff auf den HttpContext nutzt.

  public static CurrentSession GetSession()
    {
        if (HttpContext.Current.Session["MySession"] == null)
        {
            HttpContext.Current.Session["MySession"] = new CurrentSession();
        }

        return (CurrentSession)HttpContext.Current.Session["MySession"];
    }

Und in einem Unit Test auf den HttpContext zugegriffen wird, dann existiert der in den Unit Tests nicht und muss “Simuliert” werden. Dazu können wir jetzt unsere Fake DLL von “System.Web” Nutzen. Ich habe hier eine Statische Funktion erstellt, da ich auf das gleiche Konstrukt noch öfter zugreifen muss.

public static void LoadCurrentSession()
{
     var session = new System.Web.SessionState.Fakes.ShimHttpSessionState();
     session.ItemGetString = key =>
     {
           if (key == "MySession")
           {
               return new CurrentSession();
            }
           return null;
      };

      var context = new ShimHttpContext();
      ShimHttpContext.CurrentGet = () =>
      {
         return context;
      };

       ShimHttpContext.AllInstances.SessionGet = p => { return session; };
}

Das Ganze muss dann im Test z.B. so aufgerufen werden:

using (ShimsContext.Create())
{
     LoadCurrentSession()
     
     //Test durchführen in dem z.b. auf den HttpContext.Current.Session zugefriffen wird,
     //Dann wird hier unser Fake Kontext verwendet.
}

Das Ganze geht auch wenn man auf die Items des aktuellen HttpContexts zugreifen will.

public static GetContextData()
{
    if (HttpContext.Current.Items["MyItem1"] == null)
    {
        HttpContext.Current.Items.Add("MyItem1", "Hallo");
    }

    return (string)HttpContext.Current.Items["MyItem1"];
}

Die passende Hilfsfunktion für den Test würde dann folgendermaßen aussehen

public static void LoadContextItem(string itemName)
{
      var context = new ShimHttpContext();
      ShimHttpContext.CurrentGet = () =>
      {
           return context;
       };

        ShimHttpContext.AllInstances.ItemsGet = (p) => { return new ListDictionary() {{ itemName, „blubb“}}; };
}

Wenn man dann im Test wieder auf den Kontext zugreift und sein Item haben möchte, dann kann man hier wieder folgendermaßen darauf zugreifen.

using (ShimsContext.Create())
{
    LoadContextItem("MyItem1");
    
    //Test durchführen und auf das Passende Item zugreifen

}

Quellen:

http://msdn.microsoft.com/en-us/library/hh549175.aspx

http://blogs.msdn.com/b/visualstudioalm/archive/2013/02/11/february-ctp-for-visual-studio-update-2.aspx

http://blog.christopheargento.net/2013/02/02/testing-untestable-code-thanks-to-ms-fakes/

Advertisements

Ein Gedanke zu „VS 2012 Fake DLLs für Tests (stubs und shims)

  1. Pingback: ASP.NET MVC & TDD mit Unit Tests “Grundlagen” – Part 1 | SquadWuschel's Blog

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s