Montag, 2. Juli 2007

Stub vs. Mock

In einem anderen Post habe ich die vier Test Doubles beschrieben und deren Verwendung abgegrenzt. Da Mocks und Stubs immer wieder verwechselt werden, hier ein Beispiel, um deren unterschiedliche Verwendung aufzuzeigen:

Nehmen wir an, es gibt eine Funktion um das Password zu ändern. Wenn man diese aufruft, soll automatisch ein re-login mit den neuen Credentials durchgeführt werden.


public interface LoginService {
   public boolean login (String login, String password);
}


public class LoginServiceStub implements LoginService {
   private Map currentSessions = new HashMap();
   public boolean login (String login, String password) {
      currentSessions.put(login, password);
      return true;
   }
   public int numberOfCurrentSessions() {
      return currentSessions.size();
   }
}


Beim ChangePassword kann man wie folgt testen, ob login aufgerufen wird (state verification):

class ChangePasswordStateTester...
   public void testReLoginAfterPasswordChanged() {
      LoginService loginService = new LoginServiceStub();
      ChangePasswordService systemUnderTest = new ChangePasswordServiceImpl(loginService);
      systemUnderTest.changePassword("accountId", "oldPassword", "newPassword");
      assertEquals(1, loginService.numberOfCurrentSessions());
   }


Der Mock Test dazu sieht folgendermassen aus:

class ChangePasswordInteractionTester...
   public void testReLoginAfterPasswordChanged() {
      Mock loginService = mock(LoginService.class);
      ChangePasswordService systemUnderTest = new ChangePasswordServiceImpl(
         (LoginService) loginService.proxy());

      loginService.expects(once()).method("login")
         .withAnyArguments()
         .will(returnValue(true));

      systemUnderTest.changePassword("accountId",
         "oldPassword", "newPassword");
   }
}


Bei beiden Beispielen wurden Test Doubles verwendet, nicht der "echte" Login Service, wobei der Stub ein state verfication und der Mock eine behaviour verfication durchführt.

Man muss sich bewusst sein, dass man bei Stubs in aller Regel zusätzliche Methoden hinzufügen muss, um den Status zu prüfen. Das bedeutet, dass die Code Basis wächst und dieser Code wird zunehmens anfälliger und muss gewartet werden. Nicht zuletzt eine Frage der Kosten.

1 Kommentar:

Jan Schubert hat gesagt…

Wir nutzen in unserer Firma Mocks. Dies hat sich bewehrt und es muss kein zusätzlicher Code geschrieben werden. Allerdings muss beim Mocken immer sichergestellt werden, dass es eine hohe Testabdeckung gibt, da man sich durch die Mocks von vielem abtrennt!