RhinoMock如何确保不再调用任何方法

时间:2019-06-26 15:10:10

标签: c# unit-testing rhino-mocks

我有一个类似下面的代码。 (下面是伪代码)。

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

尝试使用BackToRecordReplayAll,但无法达到目标。调用AssertWasNotCalled后,调用Stop()不会失败。

有什么方法可以达到同样的效果吗?

2 个答案:

答案 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时,它将失败,因为只会发生一次呼叫。