-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Overriding services for functional testing #8203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
On Symfony master, CachePoolClearCommandTest I see this code protected function setUp()
{
static::bootKernel(array('test_case' => 'CachePoolClear', 'root_config' => 'config.yml'));
} And on KernelTestCase I see this protected static function bootKernel(array $options = array())
{
static::ensureKernelShutdown();
static::$kernel = static::createKernel($options);
static::$kernel->boot();
return static::$kernel;
}
protected static function createKernel(array $options = array())
{
if (null === static::$class) {
static::$class = static::getKernelClass();
}
return new static::$class(
isset($options['environment']) ? $options['environment'] : 'test',
isset($options['debug']) ? $options['debug'] : true
);
} Maybe I completly miss the point, but what is the idea on «loading test specific config» here, if |
Upd.: sorry, I got that Symfony have different |
Hi @chalasr, I hope someone will write good example about doing that the Right Way. I tried and now I give up. public function setUp()
{
static::bootKernel();
}
protected static function createKernel(array $opt = [])
{
return new class('test', true) extends \AppKernel
{
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(__DIR__ . '/my_config_with_mocked_service.yml');
}
};
} This Schrödinger testcase works well, if it was executed right after cache:clear and before |
Another option that could be worth documenting is described in symfony/symfony#23311 (comment): |
I would also be interested in a way to load a configuration on a per-test case basis. Making the services public/synthetic only for the sake of testing sounds wrong. |
None of these solutions truly replace the ability to $clock = $this->createMock(Clock::class);
$clock->method('now')->willReturn(new DateTimeImmutable('2020-01-01'));
$this->container->set($clock);
$serviceUnderTest = $this->container->get(ServiceUnderTest::class);
$serviceUnderTest->doSomethingThatUsesClock(); As far as I know, every other DIC in PHP and other languages has this option. |
@afilina you can create i.e. services_test.yaml and configure that service as public. Maybe not super nice, but does the trick.
and then basing on KernelTestCase:
|
@Wojciechem I tried that, but if it's not explicitly declared as synthetic, set would have no effect, not even an exception. This opens the door to accidentally write a test that gives a false positive. This can be especially bad in the context of a |
@afilina I might have made some wrong assumptions about your use case. Do you use KernelTestCase, or just build the container? The service I mock is private, and I'm overriding it completely for test environment. However in specific case of |
Next to symfony/symfony#23311
Some people are used to
set()
a service in the container for mocking it in functional tests (see https://stackoverflow.com/a/19726963/4363634) but as of 3.3, setting/resetting a predefined service is deprecated.The right solution is to load testing specific config (symfony/symfony#21533 (comment)).
I think we should add an example to the docs.
The text was updated successfully, but these errors were encountered: