MrD*_*pan 2 c# unit-testing fakeiteasy
给定以下测试类(以及相关的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); }
Run Code Online (Sandbox Code Playgroud)
而这个测试方法(试图验证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();
}
Run Code Online (Sandbox Code Playgroud)
第一个'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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
391 次 |
| 最近记录: |