hyperf-skeleton
hyperf-skeleton copied to clipboard
Dependency injection not working during tests
Hello guys. I have a controller called UserController. And i have a UserService that call getById method that returns some object. How can i mock this call when i test UserController?
I tries this code ` /** @var \Hyperf\Di\Container $c */ $c = \Hyperf\Utils\ApplicationContext::getContainer();
$queryServiceMock = $this->createMock(QueryService::class);
$queryServiceMock->method('appByKeyAndDomain')->willReturn((object)[
'id' => 1,
'key' => 'test',
'timezone' => 'UTC'
]);
$c->set(QueryService::class, $queryServiceMock);
\Hyperf\Utils\ApplicationContext::setContainer($c);`
but it would not work.
So, i have not found a way to bound some implementation to serviceContainer during testing. It's strange for me.
So you're trying to unit test a controller class with dependency injections using Inject DI and mocking some dependency, that's right?
I was looking for this last week and found on php-di documentation that it is within best practices not to unit-test controllers that way.
Not sure if it's the right way of doing this, but i found a work around by reflecting the dependency propriety and setting its value to a mocked version of it.
It looks like this.
$controller = new UserController();
$queryServiceMock = $this->createMock(QueryService::class);
$queryServiceMock->method('appByKeyAndDomain')->willReturn((object)[
'id' => 1,
'key' => 'test',
'timezone' => 'UTC'
]);
$reflectedController = new \ReflectionClass('App\Controller\UserController');
$dependency = $reflectedController->getProperty('queryService');
$dependency->setAccessible(true);
$dependency->setValue($controller, $queryServiceMock);
$this->asserTrue(true);