FakeItEasy 断言方法调用方法

FakeItEasy assert that method call to method

我有一个用 FakeItEasy v2.2.0 编写的单元测试。

测试测试一个方法,让调用它MethodA调用MethodB

简单的class:

public class Foo
{
    public virtual void MethodA()
    {
        MethodB();
    }

    public virtual void MethodB() { }
}

简单测试:

var foo_fake = A.Fake<Foo>(options => options.CallsBaseMethods());

foo_fake.MethodA();

A.CallTo(() => foo_fake.MethodA()).MustHaveHappened()
    .Then(A.CallTo(() => foo_fake.MethodB()).MustHaveHappened());

FakeItEasy2.2.0,代码通过

但是当我们升级到 5.1.0 时,代码抛出异常:

The calls were found but not in the correct order among the calls

当我们说方法被调用时?在执行开始时,还是在执行结束时?

或者,测试这个案例的正确方法是什么?

MethodB 的调用发生并在 MethodA 完成之前完成。这解释了订单消息。它(FakeItEasy)记录在成员调用结束时调用。

为了证明我的观点,以下测试通过

A.CallTo(() => foo_fake.MethodB()).MustHaveHappened() //<-- Note MethodB checked first
    .Then(A.CallTo(() => foo_fake.MethodA()).MustHaveHappened());

我建议如下

//Arrange
var foo_fake = A.Fake<Foo>(options => options.CallsBaseMethods());
Action<Foo> subject = foo => foo.MethodA();

//Act
subject(foo_fake);

//Assert
A.CallTo(() => foo_fake.MethodA()).MustHaveHappened();
A.CallTo(() => foo_fake.MethodB()).MustHaveHappened();

更新:这是一个错误,现已修复。从 FakeItEasy 5.1.1 开始,行为恢复到 2.2.0

中的状态

我们在通话结束后记录了通话,因此在您的情况下,订单为

  • 执行方法A
  • 执行方法B
  • 记录方法B发生
  • 记录方法A发生

但是,在 3.4.2 中,我们发布了对 Setting ref argument values masks incoming argument values used to verify calls 的修复。这将我们记录通话 "sequence number" 的点从 CastleInvocationCallAdapter 移动到 FakeManager。前者会在调用 methodB.

之前记录 methodA 的调用

很遗憾这破坏了您的用例。我认为新行为是一个错误,并在 GitHub.

上创建了问题 #1583 - Calls are recorded after applying the best rule, not when received

不过,就我个人而言,我会查看测试(我认为它比您在此处介绍的更复杂)。我会接受@Nikosi 的建议,而不检查通话顺序。知道他们都被调用(或者甚至只是 methodB 被调用)可能就足够了。