Ваша архитектура должна зависеть не от класса объекта, а от интерфейсов.
Экземпляр Foo
должен в конструкторе требовать параметр, который реализует интерфейс iCalculator
. И ваш метод addBar
должен только требовать, чтобы вы передавали ему что-то, что реализует интерфейс iBar
. И объект Calculator (который был передан Foo
) должен иметь возможность выполнять метод calculate
для любого экземпляра iBar
объекта.
Теперь вы можете протестировать все три объекта изолированно, если вы предоставите Mocks с одинаковыми интерфейсами.
На самом деле «решение» - это просто применение принципа обращения зависимостей , который является одним из принципов SOLID /