【发布时间】:2012-10-22 19:01:03
【问题描述】:
我正在尝试创建一个 WPF MVVM 视图模型,该模型具有注入 System.Timing.Timer 的依赖项,并希望使用 Moq 测试该视图模型。
我围绕Timer 类编写了一个薄包装器,它有一个接口ITimer,但我不确定真正测试计时器对类的贡献的最佳方法。有没有一种“强制”模拟已过事件的好方法?其他人有更好的技术吗?
【问题讨论】:
标签: c# unit-testing moq
我正在尝试创建一个 WPF MVVM 视图模型,该模型具有注入 System.Timing.Timer 的依赖项,并希望使用 Moq 测试该视图模型。
我围绕Timer 类编写了一个薄包装器,它有一个接口ITimer,但我不确定真正测试计时器对类的贡献的最佳方法。有没有一种“强制”模拟已过事件的好方法?其他人有更好的技术吗?
【问题讨论】:
标签: c# unit-testing moq
您应该在isolation 中测试您的代码。否则,您不知道您的代码是否按预期运行,或者外部依赖是否存在一些副作用。因此,为外部资源(配置文件、计时器等)创建可模拟的包装器是将 SUT 与外部代码分开的唯一方法。
【讨论】:
Timer 周围写了一个可模拟的锡包装。我对专门模拟事件的技术更感兴趣。看来Ufuk的评论正是我要找的。span>
您可以使用像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)
【讨论】: