当在同一对象上调用两次时,MustHaveHappened失败 - c#

给定以下正在测试的类(以及相关的DTO类和接口):

public class Foo
{
    private readonly IBar _bar;

    public Foo(IBar bar) { _bar = bar; }

    public void DoStuff()
    {
        var dto = new DTO();

        dto.Num = 1;
        _bar.Test(dto);

        dto.Num = 2;
        _bar.Test(dto);
    }
}

public class DTO { public int Num { get; set; } }

public interface IBar { void Test(DTO dto); }

这个测试方法(试图验证IBar.Test()是否被调用两次:一次使用Num = 1,一次使用Num = 2):

public void TestMethod1()
{
    var bar = A.Fake<IBar>();
    var foo = new Foo(bar);
    foo.DoStuff();

    A.CallTo(() => bar.Test(A<DTO>.That.Matches(x => x.Num == 1))).MustHaveHappened();
    A.CallTo(() => bar.Test(A<DTO>.That.Matches(x => x.Num == 2))).MustHaveHappened();
}

第一个“ MustHaveHappened”调用失败。我发现这是因为两次调用IBar.Test()所使用的DTO是同一实例。如果我更改代码以使用两个不同的DTO来调用IBar.Test(),则它将按预期工作。

我的问题是:这是FakeItEasy中的错误,还是我做错了什么?

参考方案

这是正确的行为,而不是错误。 FakeItEasy记录带有参数的调用,但在调用过程中不存储参数的内部状态-它仅存储参数本身的引用/值。最后,在验证阶段,DTO对象的当前状态是Num等于2的状态,这就是FakeItEasy将对其进行验证的状态。

我不确定这种情况是否有现成的支持,但是您可以轻松地实现此解决方法(而无需创建第二个DTO对象):

var bar = A.Fake<IBar>();
var foo = new Foo(bar);
var expectedNumValues = new [] { 1, 2 };
var actualNumValues = new List<int>();
// Whenever a call to IBar.Test is made, store DTO.Num in list
A.CallTo(() => bar.Test(A<DTO>.Ignored)).Invokes(
    fakeCall =>
    {
        var dto = (DTO) fakeCall.Arguments[0];
        actualNumValues.Add(dto.Num);
    }
);

foo.DoStuff();

// this verifies that both collections contain same elements at same positions
CollectionAssert.AreEqual(expectedNumValues, actualNumValues);

与哪些运算符>>兼容 - java

我这里没有什么代码int b=3; b=b >> 1; System.out.println(b); 它可以完美工作,但是当我将变量b更改为byte,short,float,double时,它包含错误,但是对于变量int和long来说,它可以完美工作,为什么它不能与其他变量一起工作? 参考方案 位移位运算符(例如>>)与任何整数类型兼…

>> Python中的运算符 - python

>>运算符做什么?例如,以下操作10 >> 1 = 5有什么作用? 参考方案 它是右移运算符,将所有位“右移”一次。二进制10是1010移到右边变成0101这是5

Python 3运算符>>打印到文件 - python

我有以下Python代码编写项目的依赖文件。它可以在Python 2.x上正常工作,但是在使用Python 3进行测试时会报告错误。depend = None if not nmake: depend = open(".depend", "a") dependmak = open(".depend.mak&#…

剃刀付款集成->如何通过关闭按钮X检测剃刀付款模型是否关闭 - javascript

当用户关闭而无需付款时,我在CI框架中使用Razorpay,请创建razor支付模型,然后取消订单,我希望按状态更改为已取消的状态触发查询。所以我怎么能检测到这一点。我已经通过单击jQuery单击关闭功能但无法使用... javascript大神给出的解决方案 Razorpay提供了JS方法来检测模式关闭。您编写的任何JS代码都不会在结帐页面上运行,因为它是…

做什么->在python中做什么 - python

我今天看到了一个python示例,它使用了->例如,这就是我所看到的:spam = None bacon = 42 def monty_python(a:spam,b:bacon) -> "different:": pass 该代码在做什么?我不太确定我以前从未看过像这样的代码,但我真的没有得到什么 a:spam,b:baco…