Лучший способ для модульного тестирования событий с использованием NUnit и Moq? - PullRequest
6 голосов
/ 30 июня 2011

Я использую NUnit и Moq для тестирования класса, в котором есть некоторые события, и я пытаюсь найти лучший способ проверить, было ли событие запущено.Я придумал это решение, но оно выглядит немного грязным, так как мне нужно создать интерфейс для теста.В любом случае я могу сделать то же самое с меньшим количеством кода или без необходимости создавать интерфейс?

Это не так уж плохо, но я чувствую, что у кого-то может быть лучшее решение.Любые идеи приветствуются.Спасибо.

[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);
    }

Ответы [ 3 ]

4 голосов
/ 30 июня 2011

Этот тест кажется проще сделать без насмешек. Сделайте тестовое устройство двойным в качестве подписчика на событие.

_networkMonitor.Started += this.SetStartedFlag; // a private method which sets a flag in the test fixture.
_networkMonitor.Start();
Assert.That(StartedFlag, Is.True);
3 голосов
/ 24 июля 2011

Я думаю, тебе вообще не нужен moq для этого.Вы можете просто зарегистрироваться для участия в событиях и оценить, были ли они запущены (или сколько раз они были запущены):

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));
    }
0 голосов
/ 24 июля 2011

Ниже приведен фрагмент способа, которым я пользовался в прошлом для хорошего эффекта.Он просто добавляет (в моем случае) экземпляры ConnectionChangedEventArgs в List <> каждый раз, когда происходит событие.Затем делается утверждение о том, сколько событий было произведено.Надеюсь, вы поймете эту идею и сможете адаптировать ее к своим потребностям, если хотите.

[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));
}
...