On Fri, Aug 2, 2024 at 7:03 PM Nick Lockheart <li...@ageofdream.com> wrote:

> I was thinking about a similar problem this week.
>
> 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?
>
>
> Minimal code for discussion purposes:
>
>
> // conf class in global namespace
> abstract class CONF {
>    const DATABASE_HOST_NAME = 'db.example.com';
>    const DATABASE_NAME = 'production';
>    const DATABASE_USER_NAME = 'prod_user';
>    const DATABASE_PASSWORD = '123';
> }
>
>
> // conf class in test namespace:
> namespace test;
> abstract class CONF {
>    const DATABASE_HOST_NAME = 'db.sandbox.com';
>    const DATABASE_NAME = 'test';
>    const DATABASE_USER_NAME = 'test_user';
>    const DATABASE_PASSWORD = 'abc';
> }
>
>
> // SQL class in global namespace
> class SQL {
>
>    private function Init(){
>       self::$oPDO = new PDO(
>          'mysql:host='.CONF::DATABASE_HOST_NAME.
>          ';dbname='.CONF::DATABASE_NAME.';charset=utf8mb4',
>          CONF::DATABASE_USER_NAME,
>          CONF::DATABASE_PASSWORD,
>          []
>       );
>    }
> }
>
> // Testing class in test namespace:
> namespace test;
> class SQLTester {
>
>    // How do I make the SQL class see \test\CONF instead of
>    // \CONF, when SQL calls for CONF in this test scope,
>    /// without changing anything inside of the SQL class?
> }
>
>
> I think some kind of sandboxing tools would be useful for
> build/test/deployment.
>

You could hack this out using the autoloader, but it's something that the
PHP community frowns upon, imo. A much prevalent practice in the PHP
ecosystem is a Dependency Injection container. A somewhat similar concept
exists in the Javascript ecosystem with hoisting import statements and
mocking modules, but if you don't understand the system and are unaware
that order of import execution will matter on whether the mock succeeds or
not plays a huge role in making it a cumbersome and awkward system.

Regardless, it's not possible for functions as users don't control function
autoloader.
-- 
Marco Deleu

Reply via email to