Skip to content

Keep your PHPUnit mocks under strict eye of static analysis

License

Notifications You must be signed in to change notification settings

rectorphp/mockstan

Repository files navigation

PHPUnit Mocks Rules

Downloads

  • Do you use extensive mocking in your PHPUnit tests?
  • Do you want to keep your tests clean, maintainable and avoid upgrade hell in the future?
  • Do you want to have test that actually test somthing?

This set is for you!


Install

composer require rector/mockstan --dev

Note: Make sure you use phpstan/extension-installer to load necessary service configs.


AvoidAnyExpectsRule

Disallow usage of any() expectation in mocks to ensure that all mock interactions are explicitly defined and verified.

rules:
    - Rector\Mockstan\Rules\AvoidAnyExpectsRule
$someMock = $this->createMock(Service::class);
$someMock->expects($this->any())
    ->method('calculate')
    ->willReturn(10);

$someMock = $this->createMock(Service::class);
$someMock->expects($this->once())
    ->method('calculate')
    ->willReturn(10);

👍


ExplicitExpectsMockMethodRule

Require explicit expects() usage when setting up mocks to avoid silent stubs. This is reuired since PHPUnit 12 to avoid silent stubs.

rules:
    - Rector\Mockstan\Rules\ExplicitExpectsMockMethodRule
$someMock = $this->createMock(Service::class);
$someMock->method('calculate')->willReturn(10);

$someMock = $this->createMock(Service::class);
$someMock->expects($this->once())->method('calculate')->willReturn(10);

👍


ForbiddenClassToMockRule

Disallow mocking of forbidden/core classes (e.g. \DateTime, Symfony Request or RequestStack, Iterable, Symfony and Doctine event objects etc.).

rules:
    - Rector\Mockstan\Rules\ForbiddenClassToMockRule
$dateTimeMock = $this->createMock(\DateTime::class);

$dateTime = new \DateTime();

👍


NoDocumentMockingRule

Prevent mocking of Doctrine ODM document classes. Use real instances instead.

rules:
    - Rector\Mockstan\Rules\NoDocumentMockingRule
$docMock = $this->createMock(App\Document\User::class);

$user = new App\Document\User();

👍


NoDoubleConsecutiveTestMockRule

Avoid creating multiple consecutive methods mocks, one for params and other for return. Use single instead.

rules:
    - Rector\Mockstan\Rules\NoDoubleConsecutiveTestMockRule
$someMock = $this->createMock(SomeClass::class);

$someMock->expects($this->once())
    ->method('foo')
    ->willReturnOnConsecutiveCalls(...)
    ->willReturnCallback(...)

$someMock = $this->createMock(SomeClass::class);

$someMock->expects($this->once())
    ->method('foo')
    // handle params in single call
    ->willReturnCallback(...)

👍


NoEntityMockingRule

Do not mock Doctrine entity classes. Use real object instance instead.

rules:
    - Rector\Mockstan\Rules\NoEntityMockingRule
$entityMock = $this->createMock(App\Entity\Product::class);

$product = new App\Entity\Product();

👍


NoMockObjectAndRealObjectPropertyRule

Disallow assigning a mock to a property while another test uses the real object on the same property.

rules:
    - Rector\Mockstan\Rules\NoMockObjectAndRealObjectPropertyRule
$this->service = $this->createMock(Service::class);
$this->service = new Service();

$this->someMock = $this->createMock(AnotherService::class);

$this->realService = new Service();

👍


NoMockOnlyTestRule

Avoid tests that only create mocks and never assert behavior. Require meaningful assertions with at least once real object to test.

rules:
    - Rector\Mockstan\Rules\NoMockOnlyTestRule
public function testNothing()
{
    $someMock = $this->createMock(Dependency::class);

    $someMock->expects($this->once())
        ->method('doSomething')
        ->willReturn(true);

    $this->assertSame($someMock->doSomething());
}

public function testSomething()
{
    $someMock = $this->createMock(Dependency::class);
    $realObject = new RealObject($someMock);

    $this->assertTrue($realObject->doSomething());
}

👍


Happy coding!

About

Keep your PHPUnit mocks under strict eye of static analysis

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

  •  

Packages

No packages published

Languages