我正在使用FakeItEasy库为我的单元测试创建假货。
我有ClassUnderTest
我要测试方法MethodToTest(Data dataObject)
。这个方法调用一个我想虚假的接口方法:
public interface IFoo
{
void Execute(Action<IDataAccess> action);
}
public class ClassUnderTest
{
private IFoo _foo;
public ClassUnderTest(IFoo foo)
{
_foo = foo;
}
public void MethodToTest(Data dataObject)
{
_foo.Execute(dataAccess => dataAccess.Update(dataObject));
}
}
public interface IDataAccess
{
void Update(Data data);
}
public class Data
{
public int Property { get; set; }
}
在我的单元测试中,我想检查测试方法是否正确调用接口(具有正确的属性值):
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var foo = A.Fake<IFoo>(x => x.Strict());
A.CallTo(() => foo.Execute(dataAccess => dataAccess.Update(A<Data>.That.Matches(d => d.Property == 20))));
var cut = new ClassUnderTest(foo);
cut.MethodToTest(new Data { Property = 20 });
}
}
但在此测试中配置错误。我得到了例外:
测试方法TestProject1.UnitTest1.TestMethod1抛出异常: FakeItEasy.ExpectationException:调用严格伪造的非配置方法“Execute”。
有人知道我必须如何正确配置CallTo()
语句吗?
提前致谢!
答案 0 :(得分:4)
更新的例子确实有帮助,@ rhe1980。
首先说明您提供的测试:
A.CallTo
方法没有做任何事情 - 它没有设置行为(使用.Invokes
或.Returns
甚至是.DoesNothing
)或验证方法已被调用(例如.MustHaveHappened
)。 Action
似乎很难。我确实在Compare Delegates Action<T>找到了一些建议,但如果是我,我会采取稍微不同的方法。我没有尝试将Action
委托与参考模型进行比较,而是认为我可以通过捕获提供给Execute
的操作然后在IDataAccess
上运行它来模拟这一点,然后看看行动的作用。幸运的是,我们有FakeItEasy来帮助解决这个问题!
我在这次测试中取得了成功:
[TestMethod]
public void TestMethod1()
{
// Arrange
var foo = A.Fake<IFoo>(x => x.Strict());
var fakeDataAccess = A.Fake<IDataAccess>();
A.CallTo(() => foo.Execute(A<Action<IDataAccess>>.Ignored))
.Invokes((Action<IDataAccess> action)=>action(fakeDataAccess));
var cut = new ClassUnderTest(foo);
// Act
cut.MethodToTest(new Data { Property = 20 });
// Assert
A.CallTo(() => fakeDataAccess.Update(A<Data>.That.Matches(d => d.Property == 20)))
.MustHaveHappened();
}
我希望它有所帮助。
答案 1 :(得分:1)
如果我理解你的意图,你需要使用如下内容:
A.CallTo(() => foo.Execute(A<Action<IDataAccess>>.Ignored).MustHaveHappened();