如何对内部使用计时器的类进行单元测试?

Geo*_*uer 10 .net testing unit-testing timer

无论喜欢与否,偶尔你必须为内部使用计时器的类编写测试.

比如说一个类,它接收系统可用性的报告,并在系统停机时间过长时引发事件

public class SystemAvailabilityMonitor {
    public event Action SystemBecameUnavailable = delegate { };
    public event Action SystemBecameAvailable = delegate { };
    public void SystemUnavailable() {
        //..
    }
    public void SystemAvailable() {
        //..
    }
    public SystemAvailabilityMonitor(TimeSpan bufferBeforeRaisingEvent) {
        //..
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用了一些技巧(将这些作为答案发布)但我不知道其他人做了什么,因为我对我的任何一种方法都不满意.

Nat*_*Nat 8

我从响应警报的对象中提取计时器.例如,在Java中,您可以将其传递给ScheduledExecutorService.在单元测试中,我传递了一个可以确定性地控制的实现,例如jMock的DeterministicScheduler.


Tho*_*enz 5

如果你正在寻找这个问题的答案,你可能对这个博客感兴趣:http : //thorstenlorenz.blogspot.com/2009/07/mocking-timer.html

在其中我解释了一种覆盖 System.Timers.Timer 类的通常行为的方法,使其在 Start() 上触发。

这是简短的版本:

class FireOnStartTimer : System.Timers.Timer
{
public new event System.Timers.ElapsedEventHandler Elapsed;

public new void Start()
{
  this.Elapsed.Invoke(this, new EventArgs() as System.Timers.ElapsedEventArgs);
}
}
Run Code Online (Sandbox Code Playgroud)

当然,这要求您能够将计时器传递到被测类中。如果这是不可能的,那么该类的设计在可测试性方面存在缺陷,因为它不支持依赖注入。如果可以,您应该更改其设计。否则,您可能会不走运,无法测试有关该类的任何涉及其内部计时器的内容。

如需更详尽的解释,请访问博客。