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
被调用)可能就足够了。
我有一个用 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
被调用)可能就足够了。