C#单元测试 - Thread.sleep代码(X) - 如何嘲笑系统时钟 [英] C# Unit Testing - Thread.Sleep(x) - How to Mock the System Clock

查看:220
本文介绍了C#单元测试 - Thread.sleep代码(X) - 如何嘲笑系统时钟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来测试一下它确实的时间间隔后一定量的工作方法。

I have to test a method which does a certain amount of work after an interval.

while (running)
{
    ...
    // Work
    ...
    Thread.Sleep(Interval);
}



间隔传递作为参数传递给类,所以我可以传递0或1,但我很感兴趣,至于如何嘲笑系统时钟,如果这是情况并非如此。

Interval is passed in as a parameter to the class so I can just pass in 0 or 1 but I was interested as to how to mock the system clock if this wasn't the case.

在我的测试中,我想能够简单地通过时间跨度设定的时间向前的间隔的,并具有线程唤醒。

In my test I'd like to be able to simply set the time forward by TimeSpan Interval and have the thread wake up.

我从来没有写测试代码,这之前,作用在执行的线程,我敢肯定有一些陷阱,以避免 - 请随时阐述什么办法使用

I've never written tests for code which acts upon the executing thread before and I'm sure there are some pitfalls to avoid - please feel free to elaborate on what approach you use.

谢谢!

推荐答案

如果您不希望测试该线程实际上睡觉的事实,更直接的方法(和一个是可能的)是有一个ISleepService。然后,您可以嘲笑这一点,然后在你的测试不睡觉,但有确实会导致您的生产代码Thread.sleep代码的实现。

If you do not wish to test the fact that the thread actually sleeps, a more straightforward approach (and one that is possible) is to have an ISleepService. You can then mock this out, and then not sleep in your tests, but have an implementation that does cause a Thread.Sleep in your production code.

ISleepService sleepService = Container.Resolve<ISleepService>();

..

while (running)
{
    ...
    // Work
    ...
    sleepService.Sleep(Interval);
}

使用起订量

例如:

Example using Moq:

    public interface ISleepService
    {
        void Sleep(int interval);
    }

    [Test]
    public void Test()
    {
        const int Interval = 1000;

        Mock<ISleepService> sleepService = new Mock<ISleepService>();
        sleepService.Setup(s => s.Sleep(It.IsAny<int>()));
        _container.RegisterInstance(sleepService.Object);

        SomeClass someClass = _container.Resolve<SomeClass>();
        someClass.DoSomething(interval: Interval);

        //Do some asserting.

        //Optionally assert that sleep service was called
        sleepService.Verify(s => s.Sleep(Interval));
    }

    private class SomeClass
    {
        private readonly ISleepService _sleepService;

        public SomeClass(IUnityContainer container)
        {
            _sleepService = container.Resolve<ISleepService>();
        }

        public void DoSomething(int interval)
        {
            while (true)
            {
                _sleepService.Sleep(interval);
                break;
            }
        }
    }



更新

在一个design\maintenance注意,如果它是痛苦的改变SomeClass的的构造函数,或依赖注入点添加到类的用户,然后服务定位器类型模式可以帮助在这里,例如:

On a design\maintenance note, if it is painful to change the constructor of "SomeClass", or to add Dependency Injection points to the user of the class, then a service locator type pattern can help out here, e.g.:

private class SomeClass
{
    private readonly ISleepService _sleepService;

    public SomeClass()
    {
        _sleepService = ServiceLocator.Container.Resolve<ISleepService>();
    }

    public void DoSomething(int interval)
    {
        while (true)
        {
            _sleepService.Sleep(interval);
            break;
        }
    }
}

这篇关于C#单元测试 - Thread.sleep代码(X) - 如何嘲笑系统时钟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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