【问题标题】:FakeItEasy assert that method call to methodFakeItEasy 断言方法调用方法
【发布时间】:2019-04-16 03:47:44
【问题描述】:

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

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

简单类:

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());

使用 FakeItEasy 2.2.0,代码通过了。

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

找到了调用,但调用中的顺序不正确

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

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

【问题讨论】:

    标签: c# unit-testing fakeiteasy


    【解决方案1】:

    更新:这是一个错误,现已修复。从 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 的修复。这将我们记录呼叫“序列号”的点从CastleInvocationCallAdapter 移动到FakeManager。前者会在调用methodB 之前记录methodA 的调用。

    很遗憾,这会破坏您的用例。我认为新行为是一个错误,并在 GitHub 上创建了问题 #1583 - Calls are recorded after applying the best rule, not when received

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

    【讨论】:

    • @Baruch,你说你在 GitHub 上提出问题。我一直在刷新列表,但还没有看到。如果您改变了主意,我将创建一个来探索将“记录通话”调用移动到我们实际执行配置的行为之前的效果。 (我刚刚试了一下,我们现有的所有测试都通过了,但也许有理由不进行更改。)
    • 您可以考虑根据用户的喜好对其进行配置。默认值可能是在完成之后,可以选择将其更改为之前。但话又说回来,它最终可能会变成范围蔓延。
    • 你怎么看MustHaveStarted。调用 MethodA MustHaveStarted 然后调用 MethodB...
    • @BlairConrad 我现在无法打开问题,如果你这样做,我会感谢你的!
    • 我创建了问题1583。 @Nikosi,我在那里复制了你的 cmets,因为 SO cmets 不适合参与讨论。如果可以的话,让我们继续。
    【解决方案2】:

    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();
    

    【讨论】:

    • 对不起,这不是答案。你说得对,它已被贬低,但问题仍然存在。你对then的引用在哪里?
    • @Baruch yours 是一种特殊情况,因为被断言的方法会相互调用。
    • 是的,当然可以,我已经检查过了。但是您是说调用MethodBMethodA 是在 MethodB 之后调用的吗?这样说是不对的,所以测试就不清楚了。
    • 我只是报告编写代码的目的。我同意这不会很清楚。
    • @Baruch 你可以考虑在 Github 上向开发者提出这个问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多