phpstan/phpstan-phpunit

PHPUnit extensions and rules for PHPStan

Maintainers

👁 ondrejmirtes

Package info

github.com/phpstan/phpstan-phpunit

Type:phpstan-extension

pkg:composer/phpstan/phpstan-phpunit

Statistics

Installs: 111 442 770

Dependents: 8 962

Suggesters: 10

Stars: 531

Open Issues: 44

2.0.16 2026-02-14 09:05 UTC

Requires

Suggests

None

Provides

None

Conflicts

Replaces

None

MIT 6ab598e1bc106e6827fd346ae4a12b4a5d634c32

static analysis

This package is auto-updated.

Last update: 2026-06-15 22:05:01 UTC


README

👁 Build
👁 Latest Stable Version
👁 License

This extension provides following features:

  • createMock(), getMockForAbstractClass() and getMockFromWsdl() methods return an intersection type (see the detailed explanation of intersection types) of the mock object and the mocked class so that both methods from the mock object (like expects) and from the mocked class are available on the object.
  • getMock() called on MockBuilder is also supported.
  • Interprets Foo|MockObject in phpDoc so that it results in an intersection type instead of a union type.
  • Defines early terminating method calls for the PHPUnit\Framework\TestCase class to prevent undefined variable errors.
  • Specifies types of expressions passed to various assert methods like assertInstanceOf, assertTrue, assertInternalType etc.
  • Combined with PHPStan's level 4, it points out always-true and always-false asserts like assertTrue(true) etc.

It also contains this strict framework-specific rules (can be enabled separately):

  • Check that you are not using assertSame() with true as expected value. assertTrue() should be used instead.
  • Check that you are not using assertSame() with false as expected value. assertFalse() should be used instead.
  • Check that you are not using assertSame() with null as expected value. assertNull() should be used instead.
  • Check that you are not using assertSame() with count($variable) as second parameter. assertCount($variable) should be used instead.
  • Check that you are not using assertEquals() with same types (assertSame() should be used)
  • Check that you are not using assertNotEquals() with same types (assertNotSame() should be used)

How to document mock objects in phpDocs?

If you need to configure the mock even after you assign it to a property or return it from a method, you should add \PHPUnit\Framework\MockObject\MockObject to the type:

private function createFooMock(): Foo&\PHPUnit\Framework\MockObject\MockObject
{
	return $this->createMock(Foo::class);
}

public function testSomething(): void
{
	$fooMock = $this->createFooMock();
	$fooMock->method('doFoo')->will($this->returnValue('test'));
	$fooMock->doFoo();
}

If you cannot use native intersection types yet, you can use PHPDoc instead.

/**
 * @return Foo&\PHPUnit\Framework\MockObject\MockObject
 */
private function createFooMock(): Foo
{
	return $this->createMock(Foo::class);
}

Please note that the correct syntax for intersection types is Foo&\PHPUnit\Framework\MockObject\MockObject. Foo|\PHPUnit\Framework\MockObject\MockObject is also supported, but only for ecosystem and legacy reasons.

If the mock is fully configured and only the methods of the mocked class are supposed to be called on the value, it's fine to typehint only the mocked class:

private Foo $foo;

protected function setUp(): void
{
	$fooMock = $this->createMock(Foo::class);
	$fooMock->method('doFoo')->will($this->returnValue('test'));
	$this->foo = $fooMock;
}

public function testSomething(): void
{
	$this->foo->doFoo();
	// $this->foo->method() and expects() can no longer be called
}

Installation

To use this extension, require it in Composer:

composer require --dev phpstan/phpstan-phpunit

If you also install phpstan/extension-installer then you're all set!