单元测试System.Timers.Timer的 [英] unit testing system.timers.timer

查看:512
本文介绍了单元测试System.Timers.Timer的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读了单元测试与定时器和线程的问题。我发现单元测试system.threading.timers的SO问题,但我需要单元测试System.Timers.Timer的和包装类似乎并不很顺利地为这一个工作。

I've been reading over the questions about unit testing with timers and threading. I found the SO question about unit testing system.threading.timers, but I need to unit test a system.timers.timer and a wrapper class doesn't seem to work quite as smoothly for this one.

我只需要知道如何模拟定时器和/或系统时间,以反对单元测试。我似乎无法找到这个任何地方对谷歌。

I just need to know how to mock the timer and/or system time in order to unit test against it. I can't seem to find this anywhere on google.

编辑和放大器;更新: 这是有道理的,如果我提取定时通过包装它下面,我可以生成一个计时器,并用嘲讽把它与一个不同的定时器代替。相关的部分,然后把我正在注入在运行时(原始的,而不是模拟)的定时器和测试它的过去事件code。

edit & update: It makes sense that if I extract the timer by wrapping it as below, I can generate a timer and use mocking to replace it with a different timer. The relevant part is then to take that timer that I'm injecting at runtime (the original, not a mock) and test it's elapsed event code.

推荐答案

从什么包装这个阻止你?

What stops you from wrapping this one?

public interface ITimer
{
    void Start(double interval);
    void Stop();
    event ElapsedEventHandler Elapsed;
}

这是pretty的多所有的接口需求。让我们来看看这到底是怎么走(注意,你可以肯定会将更多的定时器属性,但是这是pretty的很多基本的东西,应该是足够了):

That's pretty much all your interface needs. Let's see how this could go (note that you could of course expose more Timer properties, but that's pretty much basic stuff that should be enough):

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 的嘲讽框架的选择):

Now, how would you utilize this in your testing (assuming we're using FakeItEasy as mocking framework of choice):

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);

以上示例实际上确实测试code出现这种情况的一旦计时器事件引发。考虑 MyClass的寻找这样的:

Example above actually does test the code that happens once the event on timer is raised. Consider MyClass looking like this:

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 code是否执行,由断言 ReceivedEvent 属性设置。在现实中,这种方法可能会做更多的事,但只会改变我们断言的方式 - 的想法是一样的。

In the test, we force timer to raise when we need it, and we check whether code in TimerElapsedHandler executed, by asserting ReceivedEvent property was set. In reality, this method might do more than that, but that will only change the way we do assertions - idea remains the same.

编辑:您也可以尝试 ,一个框架,允许你生成的的假货任何框架类型/方法的。但是,如果嘲讽定时器是你想要的,我会去与包装方法。

You can also try Moles, a framework that allows you to generate fakes of any framework types/methods. However, if mocking timer was all you wanted, I'd go with wrapper approach.

这篇关于单元测试System.Timers.Timer的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆