Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/symfonytest/symfonydependencyinjectiontest
Library for testing user classes related to the Symfony Dependency Injection Component
https://github.com/symfonytest/symfonydependencyinjectiontest
symfony
Last synced: 4 days ago
JSON representation
Library for testing user classes related to the Symfony Dependency Injection Component
- Host: GitHub
- URL: https://github.com/symfonytest/symfonydependencyinjectiontest
- Owner: SymfonyTest
- License: mit
- Created: 2013-09-04T07:51:48.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2024-08-09T13:24:54.000Z (5 months ago)
- Last Synced: 2024-12-19T12:06:39.647Z (4 days ago)
- Topics: symfony
- Language: PHP
- Homepage:
- Size: 247 KB
- Stars: 239
- Watchers: 15
- Forks: 48
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# SymfonyDependencyInjectionTest
*By Matthias Noback and contributors*
[![Build Status](https://github.com/SymfonyTest/SymfonyDependencyInjectionTest/actions/workflows/ci.yaml/badge.svg)](https://github.com/SymfonyTest/SymfonyDependencyInjectionTest/actions/workflows/ci.yaml)
This library contains several PHPUnit test case classes and many semantic [assertions](#list-of-assertions) which
you can use to functionally test your [container extensions](#testing-a-container-extension) (or "bundle extensions")
and [compiler passes](#testing-a-compiler-pass). It also provides the tools to functionally test your container
extension (or "bundle") configuration by verifying processed values from different types of configuration files.Besides verifying their correctness, this library will also help you to adopt a TDD approach when developing
these classes.## Installation
Using Composer:
```bash
composer require --dev matthiasnoback/symfony-dependency-injection-test
```## Usage
### Testing a container extension
To test your own container extension class ``MyExtension`` create a class and extend from
``Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase``. Then implement the
``getContainerExtensions()`` method:```php
load('services.xml');// maybe process the configuration values in $config, then:
$container->setParameter('parameter_name', 'some value');
}
}
```So in the test case you should test that after loading the container, the parameter has been set correctly:
```php
load();$this->assertContainerBuilderHasParameter('parameter_name', 'some value');
}
}
```To test the effect of different configuration values, use the first argument of ``load()``:
```php
load(['my' => ['enabled' => 'false']);...
}
}
```To prevent duplication of required configuration values, you can provide some minimal configuration, by overriding
the ``getMinimalConfiguration()`` method of the test case.### Testing a compiler pass
To test a compiler pass, create a test class and extend from
``Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase``. Then implement the ``registerCompilerPass()`` method:```php
addCompilerPass(new MyCompilerPass());
}
}
```In each test you can first set up the ``ContainerBuilder`` instance properly, depending on what your compiler pass is
expected to do. For instance you can add some definitions with specific tags you will collect. Then after the "arrange"
phase of your test, you need to "act", by calling the ``compile()``method. Finally you may enter the "assert" stage and
you should verify the correct behavior of the compiler pass by making assertions about the ``ContainerBuilder``
instance.```php
setDefinition('collecting_service_id', $collectingService);$collectedService = new Definition();
$collectedService->addTag('collect_with_method_calls');
$this->setDefinition('collected_service', $collectedService);$this->compile();
$this->assertContainerBuilderHasServiceDefinitionWithMethodCall(
'collecting_service_id',
'add',
[
new Reference('collected_service')
]
);
}
}
```#### Standard test for unobtrusiveness
The ``AbstractCompilerPassTestCase`` class always executes one specific test -
``compilation_should_not_fail_with_empty_container()`` - which makes sure that the compiler pass is unobtrusive. For
example, when your compiler pass assumes the existence of a service, an exception will be thrown, and this test will
fail:```php
getDefinition('some_service_id');...
}
}
```So you need to always add one or more guard clauses inside the ``process()`` method:
```php
hasDefinition('some_service_id')) {
return;
}$definition = $container->getDefinition('some_service_id');
...
}
}
```> #### Use ``findDefinition()`` instead of ``getDefinition()``
>
> You may not know in advance if a service id stands for a service definition, or for an alias. So instead of
> ``hasDefinition()`` and ``getDefinition()`` you may consider using ``has()`` and ``findDefinition()``. These methods
> recognize both aliases and definitions.### Test different configuration file formats
The Symfony DependencyInjection component supports many different types of configuration loaders: Yaml, XML, and
PHP files, but also closures. When you create a ``Configuration`` class for your bundle, you need to make sure that each
of these formats is supported. Special attention needs to be given to XML files.In order to verify that any type of configuration file will be correctly loaded by your bundle, you must install the
[SymfonyConfigTest](https://github.com/SymfonyTest/SymfonyConfigTest) library and create a test class that extends
from ``AbstractExtensionConfigurationTestCase``:```php
twig.extension.bar
```
```php
['twig.extension.foo', 'twig.extension.bar']
];$sources = [
__DIR__ . '/Fixtures/config.yml',
__DIR__ . '/Fixtures/config.xml',
];$this->assertProcessedConfigurationEquals($expectedConfiguration, $sources);
}
}
```## List of assertions
These are the available semantic assertions for each of the test cases shown above:
assertContainerBuilderHasService($serviceId)
- Assert that the
ContainerBuilder
for this test has a service definition with the given id. assertContainerBuilderHasService($serviceId, $expectedClass)
- Assert that the
ContainerBuilder
for this test has a service definition with the given id and class. assertContainerBuilderNotHasService($serviceId)
- Assert that the
ContainerBuilder
for this test does not have a service definition with the given id. assertContainerBuilderHasSyntheticService($serviceId)
- Assert that the
ContainerBuilder
for this test has a synthetic service with the given id. assertContainerBuilderHasAlias($aliasId)
- Assert that the
ContainerBuilder
for this test has an alias. assertContainerBuilderHasAlias($aliasId, $expectedServiceId)
- Assert that the
ContainerBuilder
for this test has an alias and that it is an alias for the given service id. assertContainerBuilderHasParameter($parameterName)
- Assert that the
ContainerBuilder
for this test has a parameter. assertContainerBuilderHasParameter($parameterName, $expectedParameterValue)
- Assert that the
ContainerBuilder
for this test has a parameter and that its value is the given value. assertContainerBuilderHasExactParameter($parameterName)
- Assert that the
ContainerBuilder
for this test has a parameter. assertContainerBuilderHasExactParameter($parameterName, $expectedParameterValue)
- Assert that the
ContainerBuilder
for this test has a parameter and that its value is the given value, as well as its type matches given value type. assertContainerBuilderHasServiceDefinitionWithArgument($serviceId, $argumentIndex)
- Assert that the
ContainerBuilder
for this test has a service definition with the given id, which has an argument at
the given index. assertContainerBuilderHasServiceDefinitionWithArgument($serviceId, $argumentIndex, $expectedValue)
- Assert that the
ContainerBuilder
for this test has a service definition with the given id, which has an argument at
the given index, and its value is the given value. assertContainerBuilderHasServiceDefinitionWithServiceLocatorArgument($serviceId, $argumentIndex, $expectedValue)
- Assert that the
ContainerBuilder
for this test has a service definition with the given id, which has an argument
at the given index, and its value is a ServiceLocator with a reference-map equal to the given value. assertContainerBuilderHasServiceDefinitionWithMethodCall($serviceId, $method, array $arguments = [], $index = null)
- Assert that the
ContainerBuilder
for this test has a service definition with the given id, which has a method call to
the given method with the given arguments. If index is provided, invocation index order of method call is asserted as well. assertContainerBuilderHasServiceDefinitionWithTag($serviceId, $tag, array $attributes = [])
- Assert that the
ContainerBuilder
for this test has a service definition with the given id, which has the given tag with the given arguments. assertContainerBuilderHasServiceDefinitionWithParent($serviceId, $parentServiceId)
- Assert that the
ContainerBuilder
for this test has a service definition with the given id which is a decorated service and it has the given parent service. assertContainerBuilderHasServiceLocator($serviceId, $expectedServiceMap)
- Assert that the
ContainerBuilder
for this test has a ServiceLocator service definition with the given id.
## Available methods to set up container
In all test cases shown above, you have access to some methods to set up the
container:
setDefinition($serviceId, $definition)
- Set a definition. The second parameter is a
Definition
class registerService($serviceId, $class)
- A shortcut for
setDefinition
. It returns aDefinition
object that can be modified if necessary. setParameter($parameterId, $parameterValue)
- Set a parameter.
## Version Guidance
| Version | Released | PHPUnit | Status |
|---------|--------------|---------------|------------|
| 6.x | Aug 8, 2024 | 10.5 and 11.x | Latest |
| 5.x | Nov 22, 2023 | 9.6 and 10.x | Bugfixes |
| 4.x | Mar 28, 2019 | 8.x and 9.x | Bugfixes |
| 3.x | Mar 5, 2018 | 7.x | Bugfixes |
| 2.x | May 9, 2017 | 6.x | Bugfixes |
| 1.x | Jul 4, 2016 | 4.x and 5.x | EOL |