Проблемы возникают из-за того, как вы создаете фальшивку, и того, что вы впоследствии ожидаете от нее:
var executor = A.Fake<IActionExecutor>();
// ...
executor.Configure()
.CallsTo(x => x.TransactionalExecutionOf(A<Action>.Ignored))
.CallsBaseMethod();
Какой базовый метод ? FakeItEasy понятия не имеет, что такое базовый класс, и, следовательно, исключение DynamicProxy2
во втором случае. Вы можете создать частичное макетирование следующим образом:
var executor = A.Fake<ActionExecutor>();
Обратите внимание, что мы основываемся на фактической реализации, а не на интерфейсе
Это, однако, создает новый набор проблем, поскольку методы в ActionExecutor
не являются виртуальными, и поэтому перехватчик не может их правильно перехватить. Чтобы ваша текущая настройка работала, вам нужно изменить ActionExecutor
и сделать (все) методы виртуальными.
Однако вы можете (или даже должны) хотеть избежать изменений существующего кода (что иногда может даже не быть вариантом). Затем вы можете настроить вашу IActionExecutor
подделку следующим образом:
var executor = A.Fake<IActionExecutor>();
A.CallTo(() => executor.TransactionalExecutionOf(A<Action>.Ignored))
.Invokes(f => new ActionExecutor()
.TransactionalExecutionOf((Action)f.Arguments.First())
);
Это позволит вам работать с поддельным объектом, за исключением вызова TransactionalExecutionOf
, который будет перенаправлен на фактическую реализацию.