When we start using Symfony 2 on several projects, we find that our projects have quite a lot of code. So, we started to extract functions in Symfony 2 packages to share them between our projects.
While we mainly worked, there were many questions left that were not easy to handle, especially when it comes to testing the general package.
The first small package we extracted contains Entity-Doctrine, a kernel.event_listener , which is automatically inserted into the client project's DI container, annotation, another service, and a couple of commands. The main idea is that a client project can annotate its controllers with our annotation, event_listener will intercept requests to annotated controllers and execute some additional logic (including the doctrine object) before the controller is called. The commands are for administering the database records of the doctrine object.
So far, everything works exactly as we expected, but we are struggling with the possibility of testing only one package. First, the Git repository that contains the package does not contain the complete Symfony2 project. That would be redundant, since we are only building a package here, not an entire application, right?
But how can we test an event listener? How can we test its injection into a DI container? We need a test controller that will be annotated using our special annotation, so we can verify that our event listener correctly captures it. This controller should be available only during testing and should never appear in any client application.
How can we test the teams? We need to make fun of the database behind the doctrine. When we try to execute the command in the phpunit test, which just loads with /vendor/autoload.php , we get:
Fatal error: calling undefinedSymfony \ Component \ Console \ Application :: getKernel () method in /.../vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php on line 3
So, it looks like we still need the whole Symfony2 project in our package repository to load the whole structure, in order to ultimately test our components. When I looked at the open source packages of Symfony2, I did not find any that had the entire Framework included in their Git repositories, so it still seems to be wrong.
What am I missing? Is there any part of the Bundle-Only / Applicationless bundle development documentation that I skip?
Edit:
I found a solution for testing teams here: http://www.ricardclau.com/2013/02/testing-symfony2-commands-mocking-the-di-container-with-mockery/
It turned out that the error came from ContainerAwareCommand , trying to create a new container, which, obviously, will not work in a test environment. I solved the problem by mocking the container and manually entering it into the command like this:
use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; class MyCommandTest extends \PHPUnit_Framework_TestCase { public function testExecute() { $application = new Application(); $application->add(new MyCommand()); $command = $application->find('my:command'); $command->setContainer($this->getMockContainer());
I think Controller testing should work in a similar, mock-heavy way. When I find a solution for this, I will post the full answer here ...