Ответ 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, которая позволяет вам генерировать подделки любых типов/методов. Однако, если бы насмехался таймер, я бы пошел с оберткой.