我有一个类似下面的代码。 (下面是伪代码)。
public interface IDependency
{
void Foo();
}
public class MainClass{
Timer tmr = new Timer(100);
IDependency dependency;
public MainClass(IDependency dep)
{
dependency = dep;
tmr.Elapsed += OnElapsed;
}
void OnElapsed(object sender, EventArgs e)
{
dependency.Foo();
}
public void Start()=> tmr.Start();
public void Stop() => tmr.Stop();
}
使用RhinoMock和/或nunit,我要进行单元测试,一旦调用“ Stop”,就不再调用IDependency.Foo
尝试使用BackToRecord
和ReplayAll
,但无法达到目标。调用AssertWasNotCalled
后,调用Stop()
不会失败。
有什么方法可以达到同样的效果吗?
答案 0 :(得分:1)
在Nkosi回答之后,这是您与Rhino Mocks一起使用的方法(另请参见this question中的一些讨论):
[Test]
public async Task MainClass_Should_Stop() {
//Arrange
var dependency = MockRepository.GenerateMock<IDependency>();
var subject = new MainClass(dependency);
var expectedDelay = 200;
var expectedCalls = 2;
//Act
subject.Start();
await Task.Delay(expectedDelay);
subject.Stop();
await Task.Delay(100);
//Assert
dependency.AssertWasCalled(
dependency => dependency.Foo(),
options => options.Repeat.Times(expectedCalls)
);
}
答案 1 :(得分:0)
由于知道了计时器的间隔,因此您可以等待设置的时间并计算计时器调用Foo
的次数。
例如
[TestMethod]
public async Task MainClass_Should_Stop() {
//Arrange
var dependency = Substitute.For<IDependency>();
var subject = new MainClass(dependency);
var expectedDelay = 200;
var expectedCalls = 2;
//Act
subject.Start();
await Task.Delay(expectedDelay);
subject.Stop();
await Task.Delay(100);
//Assert
dependency.Received(expectedCalls).Foo();
}
尽管以上使用NSubstitute,但可以在您选择的模拟框架中应用同样的方法。
如果我将预期的延迟更改为一个会导致预期的呼叫不同的延迟,则测试将失败。
例如,当延迟设置为100ms并且呼叫保持在2时,它将失败,因为只会发生一次呼叫。