使用Moq模拟一个C#计时器

8

我正在尝试创建一个具有依赖注入的WPF MVVM视图模型System.Timing.Timer,并希望使用Moq测试视图模型。

我编写了一个围绕Timer类的薄包装器,其中有一个接口ITimer,但是我不确定真正测试计时器对该类的贡献的最佳方法。是否有一种好的方法来“强制”模拟经过的事件?还是有其他更好的技巧?


3
请看这个问题和这个问题 - Ufuk Hacıoğulları
谢谢,我已经在Google上搜索了一些相关的内容,但是我的查询主要集中在事件方面而不是定时器,所以找不到太多好的结果。 - Chris Covert
2个回答

3

你应该在隔离环境下测试你的代码。否则,你就无法知道你的代码是否按照预期行事,或者是否存在某些外部依赖的副作用。因此,创建可模拟的外部资源包装器(配置文件、定时器等)是将SUT与外部代码分离的唯一方式。


我了解隔离的概念,因此我编写了一个可模拟的包装器来封装 Timer。我更感兴趣的是针对事件进行模拟的技术。Ufuk 的评论似乎是我需要的。 - Chris Covert
触发事件只是通过模拟在您的模型上调用某些操作。我认为这没有什么奇怪的。 - Sergey Berezovskiy

0

你可以使用像Moq这样的框架来触发事件。你也可以这样创建一个FakeTimer

public class FakeTimer : IMyTimer
{
    private event ElapsedEventHandler elaspedHandler;
    private bool _enabled;

    public void Dispose() => throw new NotImplementedException();

    public FakeTimer(ElapsedEventHandler elapsedHandlerWhenTimeFinished, bool startImmediately)
    {
        this.elaspedHandler = elapsedHandlerWhenTimeFinished;
        _enabled = startImmediately;
    }

    public void Start() => _enabled = true;
    public void Stop() => _enabled = false;
    public void Reset() => _enabled = true;

    internal void TimeElapsed()
    {
        if (this._enabled)
            elaspedHandler.Invoke(this, new EventArgs() as ElapsedEventArgs);
    }
}

TimeElapsed() 是在单元测试中调用以指示时间已经过去的方法。

然后它将调用与之关联的事件。

在下面的示例中,MyCallBackMethod 将在 fakeTimer.TimeElapsed() 上被调用。
var fakeTimer = new FakeTimer(350, MyCallBackMethod, false)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接