Refactoring pattern for WPF UserControls

Legacy WPF Code enthält meist eine große Anzahl von UserControls, die ihrerseits massig Logik enthalten weil kein sauberes MVVM verwendet wurde. Um diesen Umstand zu beseitige braucht man aber meist eine gute Testabdeckung um nicht versehentlich etwas kaputt zu machen. In diesem Fall bekommt man dann aber nicht selten schon Probleme das entsprechende UserControl im Test zu instanziieren, weil die InitializeComponents Methode Ressourcen akquiriert die in der Testumgebung nicht vorhanden sind, da diese nicht im GUI Thread läuft. Was also tun?

Die InitializeComponents Methode dient im Grunde nur dafür die UI des Controls zu rendern. Ihr interner Aufbau, also die eigentlichen Komponenten und auch das Verhalten des Controls, existieren auch ohne jene Methode. Für Tests brauchen wir InitializeComponents also überhaupt nicht. Um nun aber minimalinvasiv vorgehen zu können, müssen wir uns eine Stelle herauspicken, an der wir das Verhalten des Controls kurz schließen können ohne allein schon dafür einen Test zu benötigen.

Dies kann man recht einfach über eine Anpassung des Konstruktors vornehmen. Hier führen wir ein Flag als Parameter ein, dass aussagt ob die UI Komponenten initialisiert werden sollen oder nicht. Über einen Defaultparameter wird dies auf true gesetzt. Auf die Weise kann die Komponente so eingesetzt werden wie sie es bisher schon wurde, unsere Änderung wirkt sich also nicht auf die eingehenden Abhängigkeiten des Controls aus.


class MyUserControl : Usercontrols
{
   MyUserControl () : this(true)
   { }

   MyUserControl (bool initializeComponents)
   {
      if(initializeComponents)
      {
         this.InitializeComponents();
      }
   }
…
}

Im Test setzen wir den Parameter dann wiederum auf false und verhindern damit den Aufruf von InitializeComponents. Tada, es kann getestet werden, was vorher untestbar erschien, denn dieser Trick kann nicht nur für InitializeComponents genutzt werden, sondern auch für jede andere Abhängigkeit die während eines Test schädlich wäre. Sehr simpel und doch effektiv.

Kommentar hinterlassen