Este tutorial utiliza PHPUnit 9, pero funciona perfectamente con PHPUnit 10.
// composer.json
{
"require": {
"php": ">=8.1.0",
"ext-ctype": "*",
"ext-iconv": "*",
"doctrine/doctrine-bundle": "^2.8", // 2.10.2
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.4
"doctrine/orm": "^2.14", // 2.16.2
"symfony/asset": "6.3.*", // v6.3.0
"symfony/console": "6.3.*", // v6.3.4
"symfony/dotenv": "6.3.*", // v6.3.0
"symfony/flex": "^2", // v2.3.3
"symfony/framework-bundle": "6.3.*", // v6.3.5
"symfony/http-client": "6.3.*", // v6.3.5
"symfony/mailer": "6.3.*", // v6.3.5
"symfony/messenger": "6.3.*", // v6.3.5
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/runtime": "6.3.*", // v6.3.2
"symfony/security-csrf": "6.3.*", // v6.3.2
"symfony/twig-bundle": "6.3.*", // v6.3.0
"symfony/yaml": "6.3.*" // v6.3.3
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.4
"phpunit/phpunit": "^9.5", // 9.6.13
"symfony/browser-kit": "6.3.*", // v6.3.2
"symfony/css-selector": "6.3.*", // v6.3.2
"symfony/debug-bundle": "6.3.*", // v6.3.2
"symfony/maker-bundle": "^1.48", // v1.51.1
"symfony/phpunit-bridge": "^6.2", // v6.3.2
"symfony/stopwatch": "6.3.*", // v6.3.0
"symfony/web-profiler-bundle": "6.3.*", // v6.3.2
"zenstruck/foundry": "^1.35", // v1.35.0
"zenstruck/mailer-test": "^1.3", // v1.3.0
"zenstruck/messenger-test": "^1.7" // v1.7.3
}
}
5 Comments
By aware there are some edge cases where setting a service on the built test container doesn't work as expected:
This great library can help with this: https://github.com/Happyr/service-mocking
I was about to say the same thing. I ran into issues when trying to manually set a service in the container during testing. I believe it might happen more often in cases when only one (or any subset) of your tests in a class need to override the service.
I was using the happyr/service-mocking package for a while, but ran into issues regarding services that use the same class, but have different configurations. In my case the affected services were different Flysystem storages.
One possible solution might be to create a proxy (partial mock that falls back to real implementation) service, set it in the container during test setup, and then override the method behavior on it as needed. You can create a proxy with by calling
$this->createTestProxy($className, $constructorArguments)in PHPUnit, where$classNameis the class you want to proxy, and$constructorArgumentsis an array of arguments to pass in the construction of the specified class. I haven't seen this proxy method used often in documentation, blog posts, or SA questions I've looked at in my search for an alternative solution to the problem happyr/service-mocking addresses. I'm not sure why that is the case, because using proxy objects has helped me a lot in writing tests at work.Here is a possible example:
EDIT 2: Regarding Edit 1... According to the documentation overriding private services should work for Symfony 6.x or 7.x. I'm using 5.4, which does not seem to support this.
EDIT 1: After testing, I've found this specific example doesn't work because you can't overwrite a private service and the
upload.storageservice would be private with the default Flysystem config. It seems like this should be something that is allowed in theKernelTestCaseclass since you are allowed to retrieve private services even though that is normally prohibited in non-test code. So, this example would work, but only if the service you are replacing is public :/ My real-world work around currently is just making the proxy object and then manually constructing the depending service (UploadManager in this example), passing in the proxy object and retrieving services from the container as needed.Ok, so it turns out the functionality to create a test proxy (and it's supporting methods) are being deprecated. So... I guess this isn't the way to go :( According to this issue it is being deprecated solely for the fact that the author hasn't seen it used much?
Thanks for the details Joe! My mission this year is to improve the Symfony testing process experience and this is one area that needs improvement.
Hey Kevin!
Excellent point - I was not aware of that library, it seems great. By the way, if your tests are not very complex, you can create a
services_test.yamlfile and override any service definition that you may need on your functional testsCheers!
"Houston: no signs of life"
Start the conversation!