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
。因此测试失败。
我是 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
。因此测试失败。