Skip to content
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

AccessibleMock incompatible with phpunit 10 #444

Closed
liayn opened this issue Mar 20, 2023 · 2 comments · Fixed by #446
Closed

AccessibleMock incompatible with phpunit 10 #444

liayn opened this issue Mar 20, 2023 · 2 comments · Fixed by #446

Comments

@liayn
Copy link
Contributor

liayn commented Mar 20, 2023

What are you trying to achieve?

$this->getAccessibleMock(SomeClass::class)

Should work.

What do you get instead?

Error: Call to undefined method PHPUnit\Framework\MockObject\MockBuilder::setMethods()
/builds/.../.Build/vendor/typo3/testing-framework/Classes/Core/BaseTestCase.php:59

The method MockBuilder::setMethods is gone in phpunit v10.

Specify some data of the environment

  • TYPO3 testing framework version: 7.x-dev aca2f49
  • TYPO3 version: 11.5.25
  • TYPO3 installation type: composer
  • PHP version: 8.2
  • phpunit/phpunit (10.0.16)

related links

sebastianbergmann/phpunit#3687
https://medium.com/bumble-tech/working-with-partial-mocks-in-phpunit-644637e12f84
https://www.drupal.org/project/drupal/issues/3130606

@lolli42
Copy link
Member

lolli42 commented Mar 20, 2023

In Fluid standalone, I switched setMethods() to onlyMethods() ... guess we should do the same here. The difference is, that onlyMethods() excepts when a method to mock does not exist, while setMethods() did not. Various core tests that use "dummy" will need to be adapted.

@liayn
Copy link
Contributor Author

liayn commented Mar 20, 2023

The other way around ;-) setMethods excepts non-existing methods, whereas the newer onlyMethods doesn't.
Those dummy-methods now need addMethods to be used.

I guess this is indeed a breaking change for the "accessible proxy" API of the testing framework, unless we do this detection ourselves, but I tend to push this responsibility to the extension author.

lolli42 added a commit that referenced this issue Mar 27, 2023
setMethods() has been removed with phpunit 10.

$this->getAccessibleMock() used this to only
partially mock a test subject. The patch switches
to onlyMethods() now.

There is one difference: onlyMethods() fails if
a methods that should be mocked does not exist,
while setMethods() did not fail on this.

So this is more strict now. It was frequently used in
core tests mocking ['dummy'] to say "mock no method".
Those have to be switched to use 'null' as argument
to $this->getAccessibleMock() now. Also, when a class
is refactored, and a method that has been previously
mocked is removed with the refactoring, the mock has
to be adapted to remove the method-mock request from
the test as well now, otherwise the test will fail.

Releases: main, 7
Resolves: #444
lolli42 added a commit that referenced this issue Mar 27, 2023
setMethods() has been removed with phpunit 10.

$this->getAccessibleMock() used this to only
partially mock a test subject. The patch switches
to onlyMethods() now.

There is one difference: onlyMethods() fails if
a methods that should be mocked does not exist,
while setMethods() did not fail on this.

So this is more strict now. It was frequently used in
core tests mocking ['dummy'] to say "mock no method".
Those have to be switched to use 'null' as argument
to $this->getAccessibleMock() now. Also, when a class
is refactored, and a method that has been previously
mocked is removed with the refactoring, the mock has
to be adapted to remove the method-mock request from
the test as well now, otherwise the test will fail.

Releases: main, 7
Resolves: #444
lolli42 added a commit that referenced this issue Apr 6, 2023
setMethods() has been removed with phpunit 10.

$this->getAccessibleMock() used this to only
partially mock a test subject. The patch switches
to onlyMethods() now.

There is one difference: onlyMethods() fails if
a methods that should be mocked does not exist,
while setMethods() did not fail on this.

So this is more strict now. It was frequently used in
core tests mocking ['dummy'] to say "mock no method".
Those have to be switched to use 'null' as argument
to $this->getAccessibleMock() now. Also, when a class
is refactored, and a method that has been previously
mocked is removed with the refactoring, the mock has
to be adapted to remove the method-mock request from
the test as well now, otherwise the test will fail.

Rules for the second argument of getAccessibleMock():

* "keep all methods, mock nothing": Hand over 'null'
* "mock all methods": Hand over empty array [] (default)
* "mock single methods": Hand over an array with method names

Releases: main, 7
Resolves: #444
lolli42 added a commit that referenced this issue Apr 6, 2023
setMethods() has been removed with phpunit 10.

$this->getAccessibleMock() used this to only
partially mock a test subject. The patch switches
to onlyMethods() now.

There is one difference: onlyMethods() fails if
a methods that should be mocked does not exist,
while setMethods() did not fail on this.

So this is more strict now. It was frequently used in
core tests mocking ['dummy'] to say "mock no method".
Those have to be switched to use 'null' as argument
to $this->getAccessibleMock() now. Also, when a class
is refactored, and a method that has been previously
mocked is removed with the refactoring, the mock has
to be adapted to remove the method-mock request from
the test as well now, otherwise the test will fail.

Rules for the second argument of getAccessibleMock():

* "keep all methods, mock nothing": Hand over 'null'
* "mock all methods": Hand over empty array [] (default)
* "mock single methods": Hand over an array with method names

Releases: main, 7
Resolves: #444
lolli42 added a commit that referenced this issue Apr 6, 2023
setMethods() has been removed with phpunit 10.

$this->getAccessibleMock() used this to only
partially mock a test subject. The patch switches
to onlyMethods() now.

There is one difference: onlyMethods() fails if
a methods that should be mocked does not exist,
while setMethods() did not fail on this.

So this is more strict now. It was frequently used in
core tests mocking ['dummy'] to say "mock no method".
Those have to be switched to use 'null' as argument
to $this->getAccessibleMock() now. Also, when a class
is refactored, and a method that has been previously
mocked is removed with the refactoring, the mock has
to be adapted to remove the method-mock request from
the test as well now, otherwise the test will fail.

Rules for the second argument of getAccessibleMock():

* "keep all methods, mock nothing": Hand over 'null'
* "mock all methods": Hand over empty array [] (default)
* "mock single methods": Hand over an array with method names

Releases: main, 7
Resolves: #444
lolli42 added a commit that referenced this issue Apr 6, 2023
setMethods() has been removed with phpunit 10.

$this->getAccessibleMock() used this to only
partially mock a test subject. The patch switches
to onlyMethods() now.

There is one difference: onlyMethods() fails if
a methods that should be mocked does not exist,
while setMethods() did not fail on this.

So this is more strict now. It was frequently used in
core tests mocking ['dummy'] to say "mock no method".
Those have to be switched to use 'null' as argument
to $this->getAccessibleMock() now. Also, when a class
is refactored, and a method that has been previously
mocked is removed with the refactoring, the mock has
to be adapted to remove the method-mock request from
the test as well now, otherwise the test will fail.

Rules for the second argument of getAccessibleMock():

* "keep all methods, mock nothing": Hand over 'null'
* "mock all methods": Hand over empty array [] (default)
* "mock single methods": Hand over an array with method names

Releases: main, 7
Resolves: #444
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants