модульное тестирование system.timers.timer - PullRequest
13 голосов
/ 01 февраля 2012

Я перечитывал вопросы о модульном тестировании с использованием таймеров и потоков. Я нашел вопрос SO о модульном тестировании system.threading.timers, но мне нужно провести модульное тестирование system.timers.timer, и класс-обертка, похоже, не работает так гладко для этого.

Мне просто нужно знать, как смоделировать таймер и / или системное время, чтобы выполнить юнит-тестирование против него. Я не могу найти это где-нибудь в Google.

редактировать и обновлять: Имеет смысл, что если я извлечу таймер, обернув его, как показано ниже, я могу сгенерировать таймер и использовать насмешку, чтобы заменить его другим таймером. Соответствующая часть заключается в том, чтобы взять тот таймер, который я вставляю во время выполнения (оригинал, а не макет), и проверить его истекший код события.

Ответы [ 2 ]

23 голосов
/ 01 февраля 2012

Что мешает вам обернуть это?

public interface ITimer
{
    void Start(double interval);
    void Stop();
    event ElapsedEventHandler Elapsed;
}

Это почти все, что нужно вашему интерфейсу.Давайте посмотрим, как это может произойти (обратите внимание, что вы, конечно, могли бы предоставить больше Timer свойств, но этого достаточно, чтобы этого хватило):

public class MyTimer : ITimer
{
    private Timer timer = new Timer();

    public void Start(double interval)
    {
        timer.Interval = interval; 
        timer.Start();
    }

    public void Stop()
    {
        timer.Stop();
    }

    public event ElapsedEventHandler Elapsed
    {
        add { this.timer.Elapsed += value; }
        remove { this.timer.Elapsed -= value; }
    }
}

Теперь, как бы вы использовали это в своемтестирование (при условии, что мы используем FakeItEasy в качестве фреймворка выбора):

var timerFake = A.Fake<ITimer>();
var classUnderTest = new MyClass(timerFake);

// tell fake object to raise event now
timerFake.Elapsed += Raise.With<ElapsedEventArgs>(ElapsedEventArgs.Empty).Now;

// assert whatever was supposed to happen as event response, indeed did
Assert.That(classUnderTest.ReceivedEvent, Is.True);

Пример выше на самом деле действительно тестирует код, который происходит после того, каксобытие по таймеру сгенерировано .Представьте, что MyClass выглядит следующим образом:

public class MyClass
{
    private ITimer timer;

    public MyClass(ITimer timer)
    {
        this.timer = timer;
        this.timer.Elapsed += TimerElapsedHandler;
    }

    public bool ReceivedEvent { get; set; }

    private void TimerElapsedHandler(object sender, ElapsedEventArgs e)
    { 
        ReceivedEvent = true;
    }
}

В тесте мы заставляем таймер поднять, когда нам это нужно, и проверяем, выполнен ли код в TimerElapsedHandler, утверждая,ReceivedEvent свойство было установлено.В действительности, этот метод может сделать больше, но это изменит только то, как мы делаем утверждения - идея остается прежней.


Редактировать: Вы также можете попробовать Кроты , фреймворк, который позволяет генерировать подделок любых типов / методов фреймворка.Однако, если бы таймер насмешки был всем, что вы хотели, я бы использовал подход обертки.

2 голосов
/ 01 февраля 2012

Вам нужно проверить таймер или проверить код, выполняемый в каждом событии?Если это так, вы можете поместить эту логику в другой класс и просто проверить это.Вы можете доверять таймеру вызовет его ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...