我之前已经成功设置并验证了 Moq 的方法,但不知何故我无法让它工作。我对同一个例外尝试了各种答案,但没有运气。
我已经实现了观察者模式,所以我在嘲笑IObserver<T>:
var mock = new Mock<IObserver<T>>();
mock.Setup(s => s.OnCompleted());
Run Code Online (Sandbox Code Playgroud)
这里OnCompleted()看起来像
public void OnCompleted()
{
}
Run Code Online (Sandbox Code Playgroud)
现在在测试中,使用mock,我确实喜欢这样:
// observable is the SUT.
var unsubscriber = observable.Subscribe(mock.Object);
// Cause OnCompleted() to be called: I verified that there's one observer in the observers list in observable and that my break point is correctly hit.
mock.Verify(v => v.OnCompleted(), Times.AtLeastOnce);
unsubscriber.Dispose();
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Message: Moq.MockException :
Expected invocation on the mock at least once, but was never performed: v => v.OnCompleted()
Configured setups:
IObserver<T> s => s.OnCompleted()
No invocations performed.
Run Code Online (Sandbox Code Playgroud)
编辑:SUT代码
SUT 是使用工厂方法初始化的类。我在这里总结一下相关部分:
有一个初始化方法:
public void InitializeMyClass()
{
for(var i = 0; i < threads.Count; i++)
{
Task.Factory.StartNew(() => Proc())
}
this.timer = new Timer(CheckStatus, null, 0, 1000);
}
Run Code Online (Sandbox Code Playgroud)
CheckStatus方法检查启动的线程中的工作负载是否Initializer达到特定状态并引发指示完成的事件:
private void CheckStatus(object status)
{
// Inspect all background threads.
// This is simply done by observing a set of values in a concurrent dict<int, bool>.:
if (!this.concurrentDict.Values.Any(a => a))
{
this.NotifyObservers();
this.timer.Change(Timeout.Infinite, Timeout.Infinite);
}
}
Run Code Online (Sandbox Code Playgroud)
NotifyObservers()调用该OnCompleted()方法:
private void NotifyObservers()
{
foreach(o in observers)
{
o.OnCompleted();
}
}
Run Code Online (Sandbox Code Playgroud)
这可能是线程问题,或者在验证完成时计时器可能尚未调用。这意味着模拟成员在被调用时实际上尚未被调用Verify。
在验证方法调用之前,您可能需要稍等一下。
尝试在测试中的 Act 和 Assertion 之间添加延迟,以便为计时器提供足够的时间来完成其任务。
//Arrange
//...
//Act
// observable is the SUT.
var unsubscriber = observable.Subscribe(mock.Object);
// Cause OnCompleted() to be called: I verified that there's one observer in the observers list in observable and that my break point is correctly hit.
await Task.Delay(TimeSpan.FromSeconds(1.5)); //Or some known duration
//Assert
mock.Verify(v => v.OnCompleted(), Times.AtLeastOnce);
unsubscriber.Dispose();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1320 次 |
| 最近记录: |