FakeItEasy - 当调用者方法被保护覆盖时,我看不到是否调用了受保护的方法

FakeItEasy - I cannot see if a protected method was called when the caller method is protected overriden

我是 FakeItEasy 的新手,抱歉,如果解决方案显而易见。

这是重现问题的简化代码:

我有一个基地class:

public abstract class BaseClass
    {
        public void Do()
        {
            Do_Override();
        }

        protected abstract void Do_Override();
    }

和派生的:

  public class ImplementingClass: BaseClass
    {
        protected override void Do_Override()
        {
            ProtectedDo();
        }

        protected virtual void ProtectedDo()
        {

        }        
    }

在我的测试中,我想看看是否调用了 ProtectedDo()。我尝试以两种方式进行测试,但测试失败并显示相同的消息:

第一。在调试模式下,它没有进入 Do_Override()

 public class ImplementingClassShould
    {
        [Fact]
        public void Run_ProtectedDo()
        {
            var fake = A.Fake<ImplementingClass>();
            fake.Do();
            A.CallTo(fake).Where(_ => _.Method.Name == "ProtectedDo").MustHaveHappened();

        }
     }

第二。在调试模式下,它进入 Do_Override()

 public class ImplementingClassShould
    {    
        [Fact]
        public void Run_ProtectedDo_V2()
        {
            var sut = new ImplementingClass();
            var sutFakeWrapper = A.Fake<ImplementingClass>(_ => _.Wrapping(sut));
            sutFakeWrapper.Do();
            A.CallTo(sutFakeWrapper).Where(_ => _.Method.Name == "ProtectedDo").MustHaveHappened();

        }        
    }

失败信息:

就目前而言,你的测试非常好。如果你 运行 它,它会告诉你 ProtectedDo 没有被调用,这是准确的。因为 Do_Override 是虚拟的,所以 FakeItEasy 拦截了调用。 (在这种情况下,受保护不会影响事情。)

如果您不希望 Do_Override 被 FakeItEasy 拦截,您应该将 Fake 配置为 call the base method 而不是自己处理调用:

[Fact]
public void Run_ProtectedDo()
{
    var fake = A.Fake<ImplementingClass>();

    A.CallTo(fake).Where(_ => _.Method.Name == "Do_Override").CallsBaseMethod();

    fake.Do();
    A.CallTo(fake).Where(_ => _.Method.Name == "ProtectedDo").MustHaveHappened();

}

根据新增Run_ProtectedDo_V2测试更新:

我希望你已经知道了,@fmm,但测试仍然失败。这是因为当 sutFakeWrapper.Do 被调用时,它转发到包装的 sut.Do。由于 sut 是一个具体的 ImplementingClass,它调用其 Do_Override,后者又调用其 ProtectedDo,因此可以调试到 ProtectedDo 方法调用。只是 sut.ProtectedDo,不是 sutFakeWrapper.ProtectedDo。因此测试失败。