On 02/08/2024 23:00, Nick Lockheart wrote:
If class A relies on class B, but you want to swap out class B with a stub to test class A in isolation, is there a way to make every call to class B, from class A, actually call a different class during the test, without modifying class A's code?
There are libraries that do exactly this, such as Mockery's "overload" and "alias"; and some that do other transparent manipulations, like https://github.com/dg/bypass-finals
They work by generating code dynamically, based on the real code, and executing it before the real definition is loaded. The same approach could definitely be taken to replace every call to a global function, and would actually be more reliable than shadowing, because it could rewrite even calls with a leading "\" or "use function" statement.
Obviously, shadowing a function in one namespace is currently a lot easier than setting up such a rewriter; but I don't think we should let that convenience for a few use cases outweigh the benefits in performance that a change in behaviour could bring, particularly when combined with function autoloading.
-- Rowan Tommins [IMSoP]