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

Deprecate TestCase::createPartialMock() #5239

Closed
sebastianbergmann opened this issue Feb 23, 2023 · 4 comments
Closed

Deprecate TestCase::createPartialMock() #5239

sebastianbergmann opened this issue Feb 23, 2023 · 4 comments
Assignees
Labels
feature/test-doubles Test Stubs and Mock Objects type/backward-compatibility Something will be/is intentionally broken

Comments

@sebastianbergmann
Copy link
Owner

sebastianbergmann commented Feb 23, 2023

PHPUnit can automatically generate test stubs and mock objects (test doubles) based on interfaces and classes.

When it comes to doubling classes, there are limitations:

  • final, private, and static methods cannot be doubled; they retain their original behavior except for static methods which will be replaced by a method throwing an exception
  • Enumerations (enum) are final classes and therefore cannot be doubled
  • readonly classes cannot be extended by classes that are not readonly and therefore cannot be doubled

Not only because of the limitations mentioned above, but also to improve your software design, PHPUnit's documentation recommends to favour the doubling of interfaces over the doubling of classes.

For quite a while, PHPUnit has offered the createStub() and createMock() methods for creating test stubs and mock objects with best practice defaults. Furthermore, alternatives such as createPartialMock() exist, but not all of them offer the same clear separation between test double and mock object. For instance, no method named createPartialStub() exists. Such an inconsistency can lead to confusion.

As its name suggests, the createPartialMock() method can be used to create a so-called partial mock object: a mock object where not all methods of the original class are replaced with an implementation that can be configured to return a specified value, for instance, or to expect an invocation.

Partial mocking is considered a code smell as it makes it not obvious to determine whether you are calling a method that has been doubled or whether you are calling an original method.

To promote better software design, improve the readability of test code, and to reduce complexity inside PHPUnit's test double functionality, TestCase::createPartialMock() will be deprecated and then removed:

  • soft deprecation in PHPUnit 10.1 (add @deprecated annotation to the method declaration)
  • deprecation in PHPUnit 11 (using the method will trigger a deprecation)
  • removal in PHPUnit 12
@sebastianbergmann sebastianbergmann added type/backward-compatibility Something will be/is intentionally broken feature/test-doubles Test Stubs and Mock Objects labels Feb 23, 2023
@sebastianbergmann sebastianbergmann added this to the PHPUnit 11.0 milestone Feb 23, 2023
@sebastianbergmann sebastianbergmann changed the title Deprecate createPartialMock() Deprecate TestCase::createPartialMock() Feb 23, 2023
@sebastianbergmann sebastianbergmann self-assigned this Feb 23, 2023
@sebastianbergmann sebastianbergmann changed the title Deprecate TestCase::createPartialMock() Deprecate TestCase::createPartialMock() Mar 6, 2023
@sebastianbergmann sebastianbergmann removed this from the PHPUnit 11.0 milestone Apr 11, 2023
@thetechdabbler
Copy link

@sebastianbergmann this is not yet soft deprecated. Is there any change of plans?

@sebastianbergmann
Copy link
Owner Author

createPartialMock() will not be deprecated in PHPUnit 11 and will not be removed in PHPUnit 12.

@rulatir
Copy link

rulatir commented Nov 18, 2023

How do I marry the superpowers of MockBuilder (specifying constructor args, disabling original constructor, etc.) with partial mocks? And not just anyhow, but in a way that - pinky promise - won't be deprecated next morning and removed after dinner?

@rela589n
Copy link

@sebastianbergmann , sorry, I didn't get the whole point,

createPartialMock() will not be deprecated in PHPUnit 11 and will not be removed in PHPUnit 12.

So is it deprecated/removed or not? Somewhat confusing to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature/test-doubles Test Stubs and Mock Objects type/backward-compatibility Something will be/is intentionally broken
Projects
None yet
Development

No branches or pull requests

4 participants