Can't associate mock with symfony service
bogdan-dubyk opened this issue · comments
I have a lot of API calls and I want to mock API client in functional tests. Note: I run this process by Symfony command
But I'm still getting real API response
I have such a test case (simplified)
$request = new Request(
SymfonyRequest::METHOD_GET,
'https://someurl.com/Apiv3/apps'
);
$apiClientMock = \Mockery::mock(HttpClientInterface::class);
$apiClientMock
->shouldReceive('send')
->once()
->with(request)
->andReturn(new Response(HttpCode::OK, [], '{"data":"some data"}'));
$I->replaceSymfonyServiceWithMock($apiClientMock);
$I->runShellCommand('bin/console sync:apps');
and logic of replaceSymfonyServiceWithMock
inside of functional helper
/**
* @param MockInterface $object
* @param string|null $alias
* @throws \Codeception\Exception\ModuleException
*/
public function replaceSymfonyServiceWithMock(MockInterface $object, string $alias = null)
{
/** @var Symfony $symfony */
$symfony = $this->getModule('Symfony');
$testContainer = $symfony->grabService('test.service_container');
if($alias !== null) {
$alias = get_class($object);
}
$testContainer->set($alias, $object);
$symfony->persistService($alias, false);
}
Details
- Codeception version: 2.4
- PHP Version: 7.2.10
- Operating System: MacOs
- Installation type: Composer
- Suite configuration:
actor: FunctionalTester
modules:
enabled:
- Symfony:
app_path: src
kernel_class: App\Kernel
environment: test
- Doctrine2:
depends: Symfony
cleanup: true
- REST:
depends: Symfony
part: json
- Cli
- Mockery
- \Helper\Functional
I have changed $I->replaceSymfonyServiceWithMock($apiClientMock);
to $I->replaceSymfonyServiceWithMock($apiClientMock, HttpClientInterface::class);
and I'm getting error
service is private, you cannot replace it.
But I'm trying to use https://symfony.com/blog/new-in-symfony-4-1-simpler-service-testing#comment-22223. is this test.service_container
is useful only to get services from the container but not to set? If so, how can I associate service with the mocked instance?
@bogdan-dubyk Can you share the way you achieved this, or haven't you got a solution for this?
I'm also thinking about mocking services, and replace those services while running functional tests. But I'm starting to think my strategy of mocking third party API's is wrong.
I've got the same kind of situation. The application connects to several api's both third party and other api's we've developed, including Soap and REST.
To correctly test our application, I want to mock the results of those third party api's. Or the result of some application repositories which connect to those api's.
I thought of a way to replace those repositories with a Mocked version. But mocks are actually only available in unit tests, not functional tests.
I also stumbled upon the following extension https://github.com/mcustiel/codeception-http-mock which serves a webserver mocking the responses.
This issue is strongly related to #96, please check the closing comment.
It can be tricky to find the correct solution to a question that might need to be rephrased.