Подтвердить что ты не робот

Единичное тестирование system.timers.timer

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

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

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

4b9b3361

Ответ 1

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

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. На самом деле этот метод может сделать больше, чем это, но это изменит только то, как мы делаем утверждения - идея остается той же.


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

Ответ 2

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