gpt4 book ai didi

c# - 对同一对象调用两次 MustHaveHappened 失败

转载 作者:行者123 更新时间:2023-12-02 08:36:43 25 4
gpt4 key购买 nike

给定以下被测试的类(以及关联的 DTO 类和接口(interface)):

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

关于c# - 对同一对象调用两次 MustHaveHappened 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12846484/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com