Система модульного теста. Поточная обработка. Таймер в.NET

Как к модульному тесту таймер на основе Системы. Поточная обработка. Таймер в.NET Система. Поточная обработка. Таймер имеет метод обратного вызова

11
задан Ghassan Karwchan 2 March 2010 в 22:38
поделиться

4 ответа

Вы можете протестировать его, не создавая прямую зависимость от System.Threading.Timer. Вместо этого создайте интерфейс ITimer и обертку вокруг System.Threading.Timer, которая реализует его.

Сначала вам нужно преобразовать обратный вызов в событие, чтобы его можно было сделать частью интерфейса:

public delegate void TimerEventHandler(object sender, TimerEventArgs e);

public class TimerEventArgs : EventArgs
{
    public TimerEventArgs(object state)
    {
        this.State = state;
    }

    public object State { get; private set; }
}

Затем создайте интерфейс:

public interface ITimer
{
    void Change(TimeSpan dueTime, TimeSpan period);
    event TimerEventHandler Tick;
}

И обертку:

public class ThreadingTimer : ITimer, IDisposable
{
    private Timer timer;

    public ThreadingTimer(object state, TimeSpan dueTime, TimeSpan period)
    {
        timer = new Timer(TimerCallback, state, dueTime, period);
    }

    public void Change(TimeSpan dueTime, TimeSpan period)
    {
        timer.Change(dueTime, period);
    }

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

    private void TimerCallback(object state)
    {
        EventHandler tick = Tick;
        if (tick != null)
            tick(this, new TimerEventArgs(state));
    }

    public event TimerEventHandler Tick;
}

Очевидно, вы добавите любые перегрузки конструктора и/или метода Change, которые вам нужно использовать из Threading.Timer. Теперь вы можете проводить модульное тестирование всего, что зависит от ITimer с помощью поддельного таймера:

public class FakeTimer : ITimer
{
    private object state;

    public FakeTimer(object state)
    {
        this.state = state;
    }

    public void Change(TimeSpan dueTime, TimeSpan period)
    {
        // Do nothing
    }

    public void RaiseTickEvent()
    {
        EventHandler tick = Tick;
        if (tick != null)
            tick(this, new TimerEventArgs(state));
    }

    public event TimerEventHandler Tick;
}

Когда вы захотите имитировать тик, просто вызовите RaiseTickEvent на поддельном таймере.

[TestMethod]
public void Component_should_respond_to_tick
{
    ITimer timer = new FakeTimer(someState);
    MyClass c = new MyClass(timer);
    timer.RaiseTickEvent();
    Assert.AreEqual(true, c.TickOccurred);
}
10
ответ дан 3 December 2019 в 09:40
поделиться

Я буду тестировать его так же, как и любой другой класс, но с короткими временными интервалами, чтобы избежать длительного выполнения модульного теста. Другой подход - тестировать только собственный код и использовать имитатор таймера (например, NMock), но это зависит от того, как устроен ваш код. Не могли бы вы выложить несколько фрагментов кода?

.
1
ответ дан 3 December 2019 в 09:40
поделиться

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

.
0
ответ дан 3 December 2019 в 09:40
поделиться

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

Кроме того, я рекомендую вместо этого использовать MultimediaTimer - он намного точнее.

0
ответ дан 3 December 2019 в 09:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: