2011-06-29 6 views
6

Używam NUnit i Moq do testowania klasy, która ma pewne zdarzenia i próbuję znaleźć najlepszy sposób na sprawdzenie, czy zdarzenie zostało uruchomione. Wymyśliłem to rozwiązanie, ale czuję się trochę brudno, ponieważ muszę stworzyć interfejs do testu. W jaki sposób mogę zrobić to samo z mniejszym kodem lub bez konieczności tworzenia interfejsu?Lepsza metoda testowania zdarzeń jednostkowych za pomocą NUnit i Moq?

To nie jest takie złe, ale czuję, że ktoś może mieć lepsze rozwiązanie. Wszelkie pomysły są mile widziane. Dzięki.

[Test] 
    public void StartedAndStoppedEventsShouldFireWhenStartedAndStopped() 
    { 
     var mockStartedEventSubscriber = new Mock<IEventSubscriber>(); 
     var mockStoppedEventSubscriber = new Mock<IEventSubscriber>(); 

     _NetworkMonitor.Started += mockStartedEventSubscriber.Object.Handler; 
     _NetworkMonitor.Stopped += mockStoppedEventSubscriber.Object.Handler; 

     _NetworkMonitor.Start(); 
     _NetworkMonitor.Stop(); 

     Func<bool> func =() => { return (eNetworkMonitorStatus.Stopped == _NetworkMonitor.Status); }; 
     Utilities.WaitUntilTrue(func, _NetworkMonitor.Interval * 2, 10); 

     _NetworkMonitor.Started -= mockStartedEventSubscriber.Object.Handler; 
     _NetworkMonitor.Stopped -= mockStoppedEventSubscriber.Object.Handler; 

     mockStartedEventSubscriber.Verify(h => h.Handler(_NetworkMonitor, EventArgs.Empty), Times.Once()); 
     mockStoppedEventSubscriber.Verify(h => h.Handler(_NetworkMonitor, EventArgs.Empty), Times.Once()); 
    } 

    public interface IEventSubscriber 
    { 
     void Handler(object sender, EventArgs e); 
    } 

Odpowiedz

4

Ten test wydaje się łatwiejszy bez makiet. Ustaw urządzenie testowe dwukrotnie jako subskrybenta zdarzenia.

_networkMonitor.Started += this.SetStartedFlag; // a private method which sets a flag in the test fixture. 
_networkMonitor.Start(); 
Assert.That(StartedFlag, Is.True); 
+0

Musiałbym stworzyć nową flagę i nową metodę dla każdego zdarzenia, które testowałem. To by dodało sporo przyduszenia. W tym przykładzie mogę użyć tego samego interfejsu. Ale widzę, co mówisz. –

+0

@Dusty Lau - Można użyć flagi ogólnej (NotificationReceived) i obsługi, ponieważ wszystko, co chcesz przetestować, jest wyzwalane przez zdarzenie. Jeśli testujesz interfejs, np. INotifyPropertyChanged, możesz napisać klasę narzędzia PropertyChangeListener, która działała z każdą implementacją interfejsu. – Gishu

0

Poniżej znajduje się fragment sposobu, z którego korzystałem w przeszłości z dobrym skutkiem. Po prostu dodaje (w moim przypadku) wystąpienia ConnectionChangedEventArgs do listy <> za każdym razem, gdy zdarzenie jest uruchamiane. Następnie pojawia się twierdzenie o tym, ile zdarzeń zostało wystrzelonych. Mam nadzieję, że otrzymasz pomysł i możesz go dostosować do własnych potrzeb, jeśli sobie tego życzysz.

[Test] 
public void GoodConnectionRaisesConnectionChangedEvent() 
{ 
    const int EXPECTED = 1; 
    List<ConnectionChangedEventArgs> ev = new List<ConnectionChangedEventArgs>(); 

    // Mocks and setup stuff here... 

    using (PlcController pc = new PlcController(mock.Object)) 
    { 
     pc.ConnectionChanged += delegate(object sender, ConnectionChangedEventArgs e) 
     { 
      ev.Add(e); 
     }; 

     pc.Connect(); 
    } 

    Assert.That(ev.Count, Is.EqualTo(EXPECTED)); 
} 
+0

Głos w dół mogę obsłużyć, ale proszę, skomentuj, dlaczego! – Andy

3

Myślę, że nie potrzebujesz do tego wcale. Możesz po prostu zarejestrować się na zdarzenia i ocenić, czy zostały one uruchomione (lub liczba razy, kiedy zostały zwolnione):

public class NetworkMonitor 
    { 
     public event EventHandler Started; 
     public event EventHandler Stopped; 

     public void Start() 
     { 
      var handler = Started; 
      if (handler != null) 
       handler(this, EventArgs.Empty); 
     } 

     public void Stop() 
     { 
      var handler = Stopped; 
      if (handler != null) 
       handler(this, EventArgs.Empty); 
     } 

    } 

    [Test] 
    public void StartedAndStoppedEventsShouldFireWhenStartedAndStopped() 
    { 

     NetworkMonitor classUnderTest = new NetworkMonitor(); 
     bool startedWasFired = false; 
     int stoppedWasFired = 0; 
     classUnderTest.Started += (o, e) => { startedWasFired = true; }; 
     classUnderTest.Stopped += (o, e) => { stoppedWasFired++; }; 

     classUnderTest.Start(); 
     Assert.That(startedWasFired); 
     classUnderTest.Stop(); 
     Assert.That(stoppedWasFired, Is.EqualTo(1)); 
    }