hyperf-skeleton icon indicating copy to clipboard operation
hyperf-skeleton copied to clipboard

Dependency injection not working during tests

Open Spartaques opened this issue 2 years ago • 2 comments

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.

Spartaques avatar Jan 04 '22 14:01 Spartaques

So, i have not found a way to bound some implementation to serviceContainer during testing. It's strange for me.

Spartaques avatar Jan 04 '22 14:01 Spartaques

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);

Castrozan avatar Oct 21 '23 14:10 Castrozan