Thomas Bandt

Über mich | Kontakt | Archiv

Rhino: AssertWasCalled wirft mysteriöse ExpectationViolationException

Weil es mich wohl Stunden und graue Haare gekostet hätte, die Lösung aber so einfach ist, sei es kurz erwähnt. Angenommen man hat eine Methode, die zwei Strings als Parameter entgegennimmt:

   1:  public void Send(string sender, string recipient)
   2:  {
   3:  }

Nun ändert sich der Typ eines Parameters von String in einen "komplexen" Typ, weil er in diesem Fall beispielsweise mehrere Adressen enthalten soll:

   1:  public class EmailRecipient
   2:  {
   3:      public string To { get; set; }
   4:      public string CC { get; set; }
   5:      public string Bcc { get; set; }
   6:  }
   7:   
   8:  public void Send(string sender, EmailRecipient recipient)
   9:  {
  10:  }

Alles schön und gut - aber nur solange man die Methode Send() nicht mittels RhinoMocks auf ihren Aufruf hin testet, üblicherweise in einem UnitTest:

   1:  [TestMethod]
   2:  public void ChangeEmail_POST_sendet_eine_Aktivierungs_Email_an_den_Benutzer()
   3:  {
   4:      // Snipp (Nicht vorhandene Logik des Tests nicht beachten :))
   5:      notificationService.AssertWasCalled(
   6:          n => n.Send(configurationService.GetValue("Email.Sender"), 
   7:              new EmailRecipient { To = "abc@efg.hij" });
   8:  }

Hier nämlich klappt nun nichts mehr. Müsste AssertWasCalled, sofern wir annehmen, dass der vorher ausgeführte und somit getestete Code, den ich hier weggelassen habe, erfolgreich ausgeführt wurde, erfolgreich sein, schlägt es nun mit einer Rhino.Mocks.Exceptions.ExpectationViolationException fehl. Wohlgemerkt: geändert hat sich nichts, außer dass recipient von String zu EmailRecipient wurde.

Die Lösung des Problems ist so simpel wie (nicht) naheliegend: Der von RhinoMocks intern durchgeführte Vergleich der EmailRecipient-Objekte klappt nicht. Abhilfe schafft das Überschreiben der Equals()-Methode, was z.B. so aussehen könnte:

   1:  public override bool Equals(object obj)
   2:  {
   3:      var r = (EmailRecipient) obj;
   4:      return r.To == To && r.CC == CC && r.Bcc == Bcc;
   5:  }

Und siehe da: alle Tests wieder grün. Das sind so Momente, in denen ich all die TDD-Vorteile vergessen und nur noch fluchen könnte - denn diese Situationen rauben mir, zumindest derzeit noch, ne Menge der Zeit, die ich durch die Tests andernorts vielleicht einspare.

Danke daher an Stefan für den zeitsparenden Tipp!

Kommentare

  1. Albert Weinert schrieb am Mittwoch, 27. Mai 2009 08:51:00 Uhr:

    Schau mal hier.

    http://der-albert.com/archive/2009/05/27/einfacheres-mocken-von-eigenschaften-eines-objektes.aspx


« Zurück  |  Weiter »