假设我有一个这样的包装实例,Resolve方法在其中注入依赖项
var handler = this.Resolve<DeletePaymentCardHandler>();
var wrapperHandler = A.Fake<DeletePaymentCardHandler>(
o => o.Wrapping(handler));
A.CallTo(() => wrapperHandler.EnsurePaymentCardCanBeDeleted(A<DeletePaymentCard>._, A<CancellationToken>._ ))
.Returns(Task.CompletedTask);
await wrapperHandler.Handle(command, CancellationToken.None);
"句柄"方法的实现方式与类似
public async Task Handle(DeletePaymentCard msg, CancellationToken cancellationToken)
{
await this.EnsurePaymentCardCanBeDeleted(msg, cancellationToken);
var instance = await this.repository.GetById<Domain.CustomerFundingSources>(msg.CustomerId, cancellationToken);
instance.Process(msg);
await this.repository.Save(instance);
}
public virtual async Task EnsurePaymentCardCanBeDeleted(DeletePaymentCard command, CancellationToken cancellationToken)
{
return Task.CompletedTask
}
我观察到的是,Handle中的这个调用不是调用注入的存储库,而是调用FakeIseasy创建的代理?
var instance = await this.repository.GetById<Domain.CustomerFundingSources>(msg.CustomerId, cancellationToken);
我认为重点是能够只拦截对某些方法的调用,而其余的应该调用封装的实例方法?来自文件:
"默认情况下,对未显式进行包装的伪调用配置的将被转发到被包装的对象">
如果不访问DeletePaymentCardHandler
的所有代码,就不可能完全确定,但对我来说,这是什么样子:
Handle
不是虚拟的,因此将执行DeletePaymentCardHandler
中的代码,完全绕过FakeIseasy。
在Handle
中,GetById
方法在repository
字段上调用(访问repository
不是方法调用,FakeIseasy无法拦截字段访问(,该字段很可能已由伪造的DeletePaymentCardHandler
类的构造函数初始化。
如果repository
字段是从构造函数参数初始化的,FakeItEasy将提供一个Dummy存储库来满足该构造函数参数。存储库类型很可能是FakeIseasy可以伪造的,因此该值将是fake。
因此,在wrappedHandler.Handle
中,真实的Handle
代码正在调用伪repository
。
如果您想要一些其他行为,那么可能需要为fake提供与包装处理程序相同的存储库。或者,Handle
可以通过虚拟属性或方法访问存储库,该虚拟属性或方式将被FakeItEasy拦截并转发给包装的处理程序,然后该处理程序将访问Resolve
方法提供的存储库。