Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[PhpUnitBridge] Making private service deprecation warning supressor more strict #27342

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

Closed
wants to merge 1 commit into from
Closed

Conversation

arderyp
Copy link
Contributor

@arderyp arderyp commented May 22, 2018

Q A
Branch? 4.1+ (PhpUnitBridge current/master)
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #27037
License MIT
Doc PR na

This issue related to #27037 and, more specifically, to @stof's comment on #27312

shouldn't this test for the KernelTestCase instead (the parent TestCase does not have the client) 

I think this is sound logic, but I think we might even want to consider taking a step further. Really, shouldn't we be checking for extensions of Symfony\Bundle\FrameworkBundle\Test\WebTestCase? After all, WebTestCase is the class that provides the static createClient() method used for building a client, from which the (test) container is retrieved, according to the current documentation: https://symfony.com/doc/current/testing.html

@stof and @nicolas-grekas, the PR here is for KernelTestCase, but I can easily change it to check instead for WebTestCase if you think the reasoning above is sound. I've tested both against my code, and they both work, but I am struggling to think of examples whereby a (proper) client/container is used within a test without extending WebTestCase and using the official approaches documented on the page linked above. Let me know what you all think.

… fetching private services from within tests more specific to check that the source class that called the deprecated code extends KernelTestCase instead of PhpUnit's base TestCase.
@stof
Copy link
Member

stof commented May 22, 2018

I still want to see my comments in #27037 as I don't think this code should exist in the PHPUnit bridge at all (the new TestContainer should not be using any deprecated API)

@arderyp
Copy link
Contributor Author

arderyp commented May 22, 2018

@stof, the new TestContainer is not using deprecated APIs. The reason this was introduced to PhpUnitBridge was because of the following scenario:

4.0 made it impossible to fetch private services from the container. 4.1 then introduced the new TestContainer that allows us to fetch private services from the container within tests (thanks to the new TestContainer). If we are running 3.4 code, and want to make our code 4.x compliant, we start using PhpUnitBridge to weed out the deprecations. We clean up all of the issue in our non-test code where we were getting private services from the container by using proper Dependency Injection and autowiring. However, our tests are still throw warnings about accessing private services from the container within the tests themselves. However, we know that we actually can do this as of 4.1. We don't need to refactor our test code, as the warnings would suggest. So instead, as @nicolas-grekas suggested, we decided to silence these specific warnings when thrown from contexts where private services are access from within tests.

Maybe @nicolas-grekas will be able to explain better than me.

@arderyp arderyp changed the title Making PhpUnit Bridge's private service deprecation warning supressor more strict [PhpUnitBridge] Making private service deprecation warning supressor more strict May 22, 2018
if (isset($trace[3]['object'])) {
$isPrivateServiceNotice = false !== strpos($msg, ' service is private, ');
$isNoticeForContainerGetHasUsage = 'Symfony\Component\DependencyInjection\Container' === $trace[2]['class'] && in_array($trace[2]['function'], array('get', 'has'));
$noticeWasTriggeredByPhpUnitTest = $trace[3]['object'] instanceof \PHPUnit\Framework\TestCase;
if ($isPrivateServiceNotice && $isNoticeForContainerGetHasUsage && $noticeWasTriggeredByPhpUnitTest) {
$kernelTestCaseClass = 'Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this var should be removed, instanceof works better with a symbol than with a string

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(and a use statement be used instead)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should definitely be WebTestCase at least, as KernelTestCase only allows to use $kernel->getContainer()->get('private_something') in 3.x, which is always a valid deprecation

@nicolas-grekas
Copy link
Member

@stof here is how to get this situation:

composer create-project symfony/skeleton:3.4 demo
cd demo
composer req test

This will install symfony/phpunit-bridge 4.*-stable (see symfony/test-pack#3)

That's why I think this is correct and should be supported.

@nicolas-grekas nicolas-grekas added this to the 4.1 milestone May 23, 2018
@nicolas-grekas
Copy link
Member

nicolas-grekas commented May 23, 2018

From @stof

depending on how you access the container in the tests, you might get the special test container or the normal one in 4.1

this is correct: if one does $kernel->getContainer()->get('private_something'), the deprecation is valid and this will fail in 4.1 also. On the contrary, $client->getContainer()->get('private_something') works in 4.1 since the container returned by the client is the "test" one.

We have a choice to do: either favor the false positive deprecation (ie revert this altogether) or merge this PR and live with the fact that some tests might break in 4.1.

I'm mixed here, both have advantages... (and I think we cannot be more accurate than done here, unfortunately.)

@stof
Copy link
Member

stof commented May 23, 2018

we indeed cannot be more accurate without changes to the 3.4 WebTestCase, as there is currently no difference between the 2 Container::get calls in the stacktrace.

Reporting deprecation properly would require having $client->getContainer() returning a special container for which we can skip the deprecation.

@arderyp
Copy link
Contributor Author

arderyp commented May 25, 2018

We'll @stof, that's a very valid and good point. Since both of our two options outlines by @nicolas-grekas are imperfect, I suppose I'm actually in support of undoing #27037, as the code is clearly confusing the community. Hopefully users moving through 4.x deprecation in preperation for an upgrade pay close attention to the documentation and discern that they will be able to ignore certain instances of this deprecation. That is, unless we can touch the 3.4 branch to change the deprecation error to be more specific in regards to the 4.1 TestContainer implementation. But its too late to push this type of change to the 3.4 branch, isn't it?

@nicolas-grekas
Copy link
Member

Thank you for your understanding, I share this opinion. Yes, too late for 3.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants