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::getMockForTrait() #5243

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

Deprecate TestCase::getMockForTrait() #5243

sebastianbergmann opened this issue Feb 23, 2023 · 2 comments
Assignees
Labels
feature/test-doubles Test Stubs and Mock Objects type/deprecation Something will be/is deprecated
Milestone

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.

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 getMockForTrait() exist, but not all of them offer the same clear separation between test double and mock object. For instance, no method named getStubForTrait() exists. Such an inconsistency can lead to confusion.

The getMockForTrait() method returns a mock object for an otherwise empty class that uses a specified trait. All abstract methods of the given trait are mocked. This allows for testing the concrete methods of a trait.

Having to use getMockForTrait() to test something is almost always a code smell: something is not quite right with the software design of the system-under-test.

To promote better software design, improve the readability of test code, and to reduce complexity inside PHPUnit's test double functionality, TestCase::getMockForTrait() 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 self-assigned this Feb 23, 2023
sebastianbergmann added a commit to sebastianbergmann/phpunit-documentation-english that referenced this issue Feb 24, 2023
@sebastianbergmann sebastianbergmann changed the title Deprecate TestCase::getMockForTrait() Deprecate TestCase::getMockForTrait() Mar 6, 2023
@sebastianbergmann sebastianbergmann added type/deprecation Something will be/is deprecated and removed type/backward-compatibility Something will be/is intentionally broken labels Apr 11, 2023
@MegaChriz
Copy link

To convert existing tests without requiring a redesign of your code, adding a class that implements the trait and mock that seems to work.

Before:

namespace MyProject\Tests;

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase {

  public function test() {
    $mock = $this->getMockForTrait('\MyProject\MyTrait');
  }

}

After:

namespace MyProject\Tests;

use MyProject\MyTrait;
use PHPUnit\Framework\TestCase;

class MyTest extends TestCase {

  public function test() {
    $mock = $this->createMock(MyTraitMock::class);
  }

}

/**
 * Mock for MyTrait.
 */
class MyTraitMock {

  use MyTrait;

}

@websmurf
Copy link

Or a bit more dynamic with the help of an anonymous class:

    /**
     * Create an anonymous class for the provided trait.
     *
     * @param trait-string $traitName Name of the trait to create a mock for.
     */
    public function createMockForTrait(string $traitName)
    {
        return eval('return new class { use ' . $traitName . '; };');
    }

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/deprecation Something will be/is deprecated
Projects
None yet
Development

No branches or pull requests

3 participants