Set of x+ PHPStan fun and practical rules that check:
@todo
Useful for any type of PHP project, from legacy to modern stack.
composer require rector/mockstan --devNote: Make sure you use phpstan/extension-installer to load necessary service configs.
### ExplicitExpectsMockMethodRule
Require explicit `expects()` usage when setting up mocks to avoid silent stubs.
```yaml
rules:
- Rector\Mockstan\Rules\ExplicitExpectsMockMethodRule// Bad (implicit stubbing)
$mock = $this->createMock(Service::class);
$mock->method('calculate')->willReturn(10);❌
// Good (explicit expects)
$mock = $this->createMock(Service::class);
$mock->expects($this->any())->method('calculate')->willReturn(10);Disallow mocking of forbidden/core classes (e.g. \DateTime, framework internals).
rules:
- Rector\Mockstan\Rules\ForbiddenClassToMockRule// Bad
$dtMock = $this->createMock(\DateTime::class);❌
// Good
$dt = new \DateTime();Prevent mocking of document classes (persisted models) — use real instances or factories.
rules:
- Rector\Mockstan\Rules\NoDocumentMockingRule// Bad
$docMock = $this->createMock(App\Document\User::class);❌
// Good
$user = new App\Document\User();Avoid creating multiple consecutive mocks in test body that indicate poor test design.
rules:
- Rector\Mockstan\Rules\NoDoubleConsecutiveTestMockRule// Bad
$a = $this->createMock(A::class);
$b = $this->createMock(B::class);❌
// Good — combine setup or use single test-specific fixture
$a = $this->createMock(A::class);
// configure $a as needed, or refactor testDo not mock entity classes (Doctrine entities); use real entity instances.
rules:
- Rector\Mockstan\Rules\NoEntityMockingRule// Bad
$entityMock = $this->createMock(App\Entity\Product::class);❌
// Good
$product = new App\Entity\Product();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();❌
// Good — keep property consistent or isolate tests
$this->service = $this->createMock(Service::class);
// or
$this->service = new Service();👍
Detect tests that only create mocks and never assert behavior — require meaningful assertions.
rules:
- Rector\Mockstan\Rules\NoMockOnlyTestRule// Bad
public function testSomething()
{
$this->createMock(Dependency::class);
}❌
public function testSomething()
{
$dep = $this->createMock(Dependency::class);
$this->assertInstanceOf(Dependency::class, $dep);
}👍
Interface must be located in "Contract" or "Contracts" namespace
rules:
- Rector\Mockstan\Rules\CheckRequiredInterfaceInContractNamespaceRulenamespace App\Repository;
interface ProductRepositoryInterface
{
}❌
namespace App\Contract\Repository;
interface ProductRepositoryInterface
{
}👍
Happy coding!