-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Mocked methods cannot be called from the original constructor of a partially mocked class #5857
Comments
This change adds a fixture class and a MockBuilder test to showcase a regression introduced with version 11.2.0. Given is a class, where one method is mocked using the `onlyMethods()` option to check the method gets called. The method is called in the class constructor and also in other public method. Providing a test mocking that method this breaks since 11.2.0 - albeit having the count in previous version only working for calls to the mock method AFTER the constructor call. Following exception thrown is not expectd: Error: Typed property MockObject_ClassCallingMethodInConstructor_b5ada611::$__phpunit_state must not be accessed before initialization Related: sebastianbergmann#5857
This change adds a fixture class and a MockBuilder test to showcase a regression introduced with version 11.2.0. Given is a class, where one method is mocked using the `onlyMethods()` option to check the method gets called. The method is called in the class constructor and also in other public method. Providing a test mocking that method this breaks since 11.2.0 - albeit having the count in previous version only working for calls to the mock method AFTER the constructor call. In 11.1.3 this works and following exception is not recieved: Error: Typed property MockObject_ClassCallingMethodInConstructor_b5ada611::$__phpunit_state must not be accessed before initialization Related: sebastianbergmann#5857
PHPUnit 11.2 has added support for extendable classes that are declared Side note: maybe we can discuss at the TYPO3 code sprint this week whether the TYPO3 project can also test in its nightly CI pipeline with the current development version of PHPUnit. This would allow us to uncover such problems earlier. The problem you found is ultimately due to the fact that the test double functionality of PHPUnit supports not only interfaces, but also extendable classes. The fact that only a selection of the methods of an extendable class can be replaced makes the whole thing even worse. Please don't get me wrong, I don't want to deny any blame, nor do I want to blame users of PHPUnit. The only person I blame is myself and I am sorry that PHPUnit 11.2 broke your tests.
|
PHPUnit refactored the double creation to support doubling readonly classes [1], thus breaking classes where the class constructor is called with constructor arguments, but calling itself a class method which is mocked using the `onlyMethods()` setup option. This leads now to some internal state setup issue and is reported as `regression` [2] providing steps to reproduce it. This change adds `phpunit 11.2.0` as conflict to the monorepo version to avoid using it in nightly tests for now, until a proper regression fix has been implemented in phpunit. Used command(s): \ cat \ <<< $(jq --indent 1 --tab \ '."conflict" += {"phpunit/phpunit": "11.2.0"}' \ composer.json) > composer.json \ && Build/Scripts/runTests.sh -s composer -- update --lock [1] sebastianbergmann/phpunit#5804 [2] sebastianbergmann/phpunit#5857 Resolves: #104007 Releases: main Change-Id: Ia384ff98a9ea4e318738a48bd9ff8afcc4faff15 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/84533 Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Simon Schaufelberger <simonschaufi+typo3@gmail.com> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Simon Schaufelberger <simonschaufi+typo3@gmail.com> Tested-by: Stefan Bürk <stefan@buerk.tech>
I have an idea how to solve this, now I need to find time to give it a try. |
Just dropping by to say that there's no blame at all, and those nightly tests are there for us to catch things early, and search for solutions. Thank you and @sbuerk for inspecting this so quickly, and I'm sure there'll be a solution. :-) |
This change adds a fixture class and a MockBuilder test to showcase a regression introduced with version 11.2.0. Given is a class, where one method is mocked using the `onlyMethods()` option to check the method gets called. The method is called in the class constructor and also in other public method. Providing a test mocking that method this breaks since 11.2.0 - albeit having the count in previous version only working for calls to the mock method AFTER the constructor call. Following exception thrown is not expectd: Error: Typed property MockObject_ClassCallingMethodInConstructor_b5ada611::$__phpunit_state must not be accessed before initialization Related: #5857
Brief update: The confidence Garvin has shown me that I will be able to solve the problem has motivated me to continue thinking about the problem and working on a solution. I currently have the situation here (local, not committed and pushed) that @sbuerk's test is green. Whoopee! However, several other tests are red. Oh no! Let's hope that I manage to turn all the tests green again ... |
The nightly CI run recently revealed a regression within phpunit [1] which has been fixed meanwhile upstream [2] by Sebastian Bergmann. This change raises phpunit to the bugfix version and the conflict is removed. Used command(s): composer require --dev "phpunit/phpunit":"^11.2.1" [1] sebastianbergmann/phpunit#5857 [2] https://github.com/sebastianbergmann/phpunit/releases/tag/11.2.1 Resolves: #104036 Releases: main Change-Id: I8f83ca4b574d174dc0f13bb4a59ad5f35a905204 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/84595 Tested-by: Christian Kuhn <lolli@schwarzbu.ch> Reviewed-by: Garvin Hicking <gh@faktor-e.de> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Andreas Kienast <a.fernandez@scripting-base.de> Reviewed-by: Andreas Kienast <a.fernandez@scripting-base.de>
Summary
A class method is called in the constructor and in other
class methods. Using
onlyMethods()
to mock that methoddoes not regonized the calling (count) until now, but at
least subsequential calls could be tested and ensured.
This worked until 11.2.0 of phpunit and was detected in
the TYPO3 nightly pipeline automatically pulling in new
dependency versions, like phpunit.
Note: In manual tests this has been reduced to phpunit
and other dependency ruled out. Can be reproduced within
the phpunit source code directly.
Current behavior
Since 11.2.0 this no longer works and a exception like following
is thrown:
How to reproduce
This can be reproduced with a simple class:
and having a test like following:
Expected behavior
Test passes without error (green), which worked until 11.2.0.
The text was updated successfully, but these errors were encountered: