. namespace core; use PHPUnit\Framework\MockObject\Stub; use Psr\Container\ContainerInterface; /** * Tests for Moodle's Container. * * @package core * @copyright 2024 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @covers \core\di */ class di_test extends \advanced_testcase { /** * Test that the get_container method returns the Container Instance and stores it statically. */ public function test_get_container(): void { $container = di::get_container(); $this->assertInstanceOf(ContainerInterface::class, $container); $this->assertTrue($container === di::get_container()); } /** * Test that the reset_container method resets the container such that a different instance is returned. */ public function test_reset_container(): void { $instance = di::get_container(); $this->assertInstanceOf(ContainerInterface::class, $instance); di::reset_container(); $this->assertFalse($instance === di::get_container()); } /** * This test just ensures that a container can return an autowired client. * * This is standard behaviour for a Container, but we want to actually check it. */ public function test_autowired_client(): void { $container = di::get_container(); $client = $container->get(http_client::class); $this->assertInstanceOf(http_client::class, $client); // Fetching the same again. $this->assertEquals( $client, $container->get(http_client::class), ); } /** * Test that we can mock a client and set it in the container for other consumers to get. */ public function test_mocked_client(): void { $container = di::get_container(); // Create a mocked http_client. $mockedclient = $this->createStub(http_client::class); // Set it in the container. di::set(http_client::class, $mockedclient); // Fetching it out will give us the same mocked client. $client = $container->get(http_client::class); $this->assertEquals( $mockedclient, $client, ); // And the returned client will of course still be an http_client and a Stub. $this->assertInstanceOf(http_client::class, $client); $this->assertInstanceOf(Stub::class, $client); // Even after getting a new container instance. $this->assertEquals( di::get_container()->get(http_client::class), $client, ); // Resetting the container will give us a new, unmocked, instance. di::reset_container(); $client = di::get_container()->get(http_client::class); $this->assertInstanceOf(http_client::class, $client); $this->assertNotInstanceOf(Stub::class, $client); $this->assertNotEquals( $mockedclient, $client, ); } /** * Test that a mocked client can be set in one test, but is not preserved across tests. * * @return Stub The mocked client to pass to the dependant test */ public function test_mocked_client_test_one(): Stub { di::set(http_client::class, $this->createStub(http_client::class)); $mockedclient = di::get_container()->get(http_client::class); $this->assertInstanceOf(http_client::class, $mockedclient); $this->assertInstanceOf(Stub::class, $mockedclient); return $mockedclient; } /** * Test that a client mocked in a previous test does not bleed. * * @depends test_mocked_client_test_one */ public function test_mocked_client_test_two(Stub $mockedclient): void { $client = di::get_container()->get(http_client::class); $this->assertInstanceOf(http_client::class, $client); $this->assertNotInstanceOf(Stub::class, $client); $this->assertNotEquals($mockedclient, $client); } /** * Test that the container will return the $DB global as a moodle_database instance. */ public function test_fetch_moodle_database(): void { global $DB; $this->assertEquals($DB, di::get(\moodle_database::class)); } /** * Test that the hook manager is in the container. */ public function test_fetch_hook_manager(): void { $manager = di::get(hook\manager::class); $this->assertEquals($manager, hook\manager::get_instance()); } public function test_fetch_string_manager(): void { $stringmanager = di::get(\core_string_manager::class); $this->assertEquals( get_string_manager(), $stringmanager, ); } }