如何假动作<>与FakeItEasy [英] How to fake an action<> with FakeItEasy
问题描述
我正在使用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;组; }
}
在我的单元测试中,我想检查测试方法是否调用接口(正确的属性值):
[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:调用非配置方法执行的严格假货。
有人知道我如何配置 CallTo )
$ b
更新的示例真的有帮助,@ rhe1980。
您提供的测试的第一些注意事项:
-
A.CallTo
方法不做任何事情 - 它不设置行为(使用.Invokes
或.Returns
或甚至.DoesNothing
)或验证该方法是否已被调用(例如.MustHaveHappened
)。 - 比较
Action
似乎很难。我在比较代表操作< T> 找到了一些建议,但如果是我, c 委托给一个参考模型,我想我可以通过捕获执行,然后运行它在
IDataAccess
并参阅操作的作用。幸运的是,我们有FakeItEasy帮助这个!
我已经成功的测试:
[TestMethod]
public void TestMethod1()
{
// Arrange
var foo = A.Fake< IFoo>(x => x。严格());
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();
}
我希望它有帮助。
I'm working with the FakeItEasy library to create fakes for my unit tests.
I have a
ClassUnderTest
on which I want to test the methodMethodToTest(Data dataObject)
. This method is calling a method of an interface which I want to fake: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; } }
In my unit tests I want to check if the test method calls the interface correctly (with the correct property value):
[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 }); } }
But something is configured wrong in this test. I get the exception:
Test method TestProject1.UnitTest1.TestMethod1 threw exception: FakeItEasy.ExpectationException: Call to non configured method "Execute" of strict fake.
Does somebody have an idea of how I have to configure the
CallTo()
statement correctly?Thanks in advance!
解决方案The updated example really helps, @rhe1980.
First some notes about the test you supplied:
- the
A.CallTo
method doesn't do anything - it's not setting up behaviour (with a.Invokes
or a.Returns
or even a.DoesNothing
) or verifying that the method has been called (for example with.MustHaveHappened
). - Comparing
Action
s appears to be tough. I did find some advice over at Compare Delegates Action<T>, but if it were me, I'd take a slightly different tack.
Instead of attempting to compare the
Action
delegate to a reference model, I figured I could emulate this by capturing the action supplied toExecute
and then running it on anIDataAccess
and see what the action does. Fortunately, we have FakeItEasy to help with that!I had success with this test:
[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(); }
I hope it helps.
这篇关于如何假动作<>与FakeItEasy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- the