我有以下代码
public interface IFoo
{
void Execute();
}
public abstract class FooBar: IFoo
{
public void Execute()
{
OnExecute();
}
public abstract void OnExecute();
}
并按照测试用例来测试Execute()
方法
[Fact]
public void When_execute_method_called_Expect_executionTime_is_set()
{
var sutMethod = A.Fake<FooBar>();
A.CallTo(sutMethod).
Where(x => x.Method.Name == "OnExecute").
Invokes(x => Thread.Sleep(100)));
sutMethod.Execute();
Assert.NotEqual(0, sutMethod.Result.ExecutionTime.Ticks);
}
sutMethod.Execute();
来电将转至FooBar.Execute()
后来我决定将界面变成抽象类
public abstract class IFoo
{
public abstract void Execute();
}
public abstract class FooBar:IFoo
{
public override void Execute()
{
OnExecute();
}
public abstract void OnExecute();
}
现在sutMethod.Execute();
来电不会调用FooBar.Execute()
我认为FakeItEasy会将接口和抽象类处理得一样。我错过了什么?
更新 @ Blair Conrad提供了行为的推理
是否可以对测试用例进行最小的更改以恢复原始行为?
感谢
答案 0 :(得分:3)
差异是由于Execute
上方法FooBar
的可覆盖性造成的。
FakeItEasy can only override virtual members, abstract members, or interface members。
在原始示例中,当IFooBar
是一个接口而FooBar
实现它时,Execute
是一个具体的方法。它不是虚拟的,也不是抽象的。因此,FakeItEasy无法拦截对它的调用,并执行原始方法。
将IFooBar
更改为抽象类后,您会在IFooBar.Execute
中找到override
的摘要FooBar
。因此,FooBar.Execute
现在是虚拟的,可以被FakeItEasy拦截。这样做,所以你的实现不会被调用。
答案 1 :(得分:1)
以下添加帮助解决问题
Execute
这会调用FooBar
type