使用fakeiteasy

时间:2015-08-18 06:22:47

标签: interface abstract-class fakeiteasy

我有以下代码

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提供了行为的推理

是否可以对测试用例进行最小的更改以恢复原始行为?

感谢

2 个答案:

答案 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