如何在.NET中对基于System.Threading.Timer的计时器进行单元测试?
System.Threading.Timer具有回调方法。
如何在.NET中对基于System.Threading.Timer的计时器进行单元测试?
System.Threading.Timer具有回调方法。
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);
}
我会像测试其他类一样进行测试,但时间间隔较短,以避免单元测试运行太长时间。 另一种方法是仅测试您自己的代码,并使用模拟计时器(例如NMock),但这取决于您的代码设计。您能发布一些代码片段吗?
如果时间只是改变了回调方法,那么你只需要检查该方法的正确性,而不是系统时间如何工作。
除此之外,我建议使用MultimediaTimer - 它更加精确。
MultimediaTimer
给所有人吗? :) - Tim Robinson
object sender,TEventArgs e
,其中TEventArgs:EventArgs
。 - AaronaughtAction
。 - Aaronaught