PHPackages                             phpstan/phpstan-phpunit - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. phpstan/phpstan-phpunit

ActivePhpstan-extension[Testing &amp; Quality](/categories/testing)

phpstan/phpstan-phpunit
=======================

PHPUnit extensions and rules for PHPStan

2.0.17(4d ago)533113.2M—0.1%57[36 issues](https://github.com/phpstan/phpstan-phpunit/issues)[8 PRs](https://github.com/phpstan/phpstan-phpunit/pulls)20MITPHPPHP ^7.4 || ^8.0CI passing

Since Nov 26Pushed 2d ago7 watchersCompare

[ Source](https://github.com/phpstan/phpstan-phpunit)[ Packagist](https://packagist.org/packages/phpstan/phpstan-phpunit)[ RSS](/packages/phpstan-phpstan-phpunit/feed)WikiDiscussions 2.0.x Synced 2d ago

READMEChangelog (10)Dependencies (14)Versions (93)Used By (20)

PHPStan PHPUnit extensions and rules
====================================

[](#phpstan-phpunit-extensions-and-rules)

[![Build](https://github.com/phpstan/phpstan-phpunit/workflows/Build/badge.svg)](https://github.com/phpstan/phpstan-phpunit/actions)[![Latest Stable Version](https://camo.githubusercontent.com/8f40b750a84d8459b896e2d44cd426dc28da84d95b75ddba78fdd6eb9b5d1a49/68747470733a2f2f706f7365722e707567782e6f72672f7068707374616e2f7068707374616e2d706870756e69742f762f737461626c65)](https://packagist.org/packages/phpstan/phpstan-phpunit)[![License](https://camo.githubusercontent.com/8b2611aa687b31e92a61b91fe606764e7f919af0a4ca0407d55ea96e170b5ba5/68747470733a2f2f706f7365722e707567782e6f72672f7068707374616e2f7068707374616e2d706870756e69742f6c6963656e7365)](https://packagist.org/packages/phpstan/phpstan-phpunit)

- [PHPStan](https://phpstan.org/)
- [PHPUnit](https://phpunit.de)

This extension provides following features:

- `createMock()`, `getMockForAbstractClass()` and `getMockFromWsdl()` methods return an intersection type (see the [detailed explanation of intersection types](https://phpstan.org/blog/union-types-vs-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?
----------------------------------------

[](#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
------------

[](#installation)

To use this extension, require it in [Composer](https://getcomposer.org/):

```
composer require --dev phpstan/phpstan-phpunit

```

If you also install [phpstan/extension-installer](https://github.com/phpstan/extension-installer) then you're all set!

 Manual installationIf you don't want to use `phpstan/extension-installer`, include extension.neon in your project's PHPStan config:

```
includes:
    - vendor/phpstan/phpstan-phpunit/extension.neon

```

To perform framework-specific checks, include also this file:

```
    - vendor/phpstan/phpstan-phpunit/rules.neon

```

###  Health Score

81

—

ExcellentBetter than 100% of packages

Maintenance98

Actively maintained with recent releases

Popularity75

Solid adoption and visibility

Community59

Growing community involvement

Maturity84

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 55% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~38 days

Total

82

Last Release

4d ago

Major Versions

0.12.22 → 1.0.02021-10-14

1.4.0 → 2.0.02024-10-14

1.4.1 → 2.0.12024-11-12

1.4.x-dev → 2.0.22024-12-17

PHP version history (5 changes)0.9PHP ~7.0

0.10PHP ~7.1

0.12.13PHP ^7.1 || ^8.0

1.1.0PHP ^7.2 || ^8.0

2.0.0PHP ^7.4 || ^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/104888?v=4)[Ondřej Mirtes](/maintainers/ondrejmirtes)[@ondrejmirtes](https://github.com/ondrejmirtes)

---

Top Contributors

[![ondrejmirtes](https://avatars.githubusercontent.com/u/104888?v=4)](https://github.com/ondrejmirtes "ondrejmirtes (181 commits)")[![staabm](https://avatars.githubusercontent.com/u/120441?v=4)](https://github.com/staabm "staabm (34 commits)")[![renovate[bot]](https://avatars.githubusercontent.com/in/2740?v=4)](https://github.com/renovate[bot] "renovate[bot] (29 commits)")[![renovate-bot](https://avatars.githubusercontent.com/u/25180681?v=4)](https://github.com/renovate-bot "renovate-bot (10 commits)")[![villfa](https://avatars.githubusercontent.com/u/2891564?v=4)](https://github.com/villfa "villfa (9 commits)")[![mad-briller](https://avatars.githubusercontent.com/u/28307684?v=4)](https://github.com/mad-briller "mad-briller (9 commits)")[![VincentLanglet](https://avatars.githubusercontent.com/u/9052536?v=4)](https://github.com/VincentLanglet "VincentLanglet (8 commits)")[![mhujer](https://avatars.githubusercontent.com/u/353372?v=4)](https://github.com/mhujer "mhujer (7 commits)")[![lookyman](https://avatars.githubusercontent.com/u/3863468?v=4)](https://github.com/lookyman "lookyman (5 commits)")[![ruudk](https://avatars.githubusercontent.com/u/104180?v=4)](https://github.com/ruudk "ruudk (5 commits)")[![herndlm](https://avatars.githubusercontent.com/u/5738896?v=4)](https://github.com/herndlm "herndlm (3 commits)")[![canvural](https://avatars.githubusercontent.com/u/1574232?v=4)](https://github.com/canvural "canvural (3 commits)")[![lcobucci](https://avatars.githubusercontent.com/u/201963?v=4)](https://github.com/lcobucci "lcobucci (3 commits)")[![localheinz](https://avatars.githubusercontent.com/u/605483?v=4)](https://github.com/localheinz "localheinz (3 commits)")[![Kocal](https://avatars.githubusercontent.com/u/2103975?v=4)](https://github.com/Kocal "Kocal (2 commits)")[![kubawerlos](https://avatars.githubusercontent.com/u/9282069?v=4)](https://github.com/kubawerlos "kubawerlos (2 commits)")[![jeroennoten](https://avatars.githubusercontent.com/u/4370753?v=4)](https://github.com/jeroennoten "jeroennoten (2 commits)")[![PrinsFrank](https://avatars.githubusercontent.com/u/25006490?v=4)](https://github.com/PrinsFrank "PrinsFrank (2 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![Chris53897](https://avatars.githubusercontent.com/u/7104259?v=4)](https://github.com/Chris53897 "Chris53897 (1 commits)")

---

Tags

phpphp7phpstanphpunitstatic-analysisstatic-code-analysistestingstatic analysis

###  Code Quality

TestsPHPUnit

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phpstan-phpstan-phpunit/health.svg)

```
[![Health](https://phpackages.com/badges/phpstan-phpstan-phpunit/health.svg)](https://phpackages.com/packages/phpstan-phpstan-phpunit)
```

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.5k55.4M8.4k](/packages/larastan-larastan)[phpstan/phpstan-symfony

Symfony Framework extensions and rules for PHPStan

79475.7M2.2k](/packages/phpstan-phpstan-symfony)[phpstan/phpstan-doctrine

Doctrine extensions for PHPStan

67272.8M1.4k](/packages/phpstan-phpstan-doctrine)[shipmonk/dead-code-detector

Dead code detector to find unused PHP code via PHPStan extension. Can automatically remove dead PHP code. Supports libraries like Symfony, Doctrine, PHPUnit etc. Detects dead cycles. Can detect dead code that is tested.

4853.5M91](/packages/shipmonk-dead-code-detector)[phpstan/phpstan-strict-rules

Extra strict and opinionated rules for PHPStan

70370.0M5.3k](/packages/phpstan-phpstan-strict-rules)[spaze/phpstan-disallowed-calls

PHPStan rules to detect disallowed method &amp; function calls, constant, namespace, attribute, property &amp; superglobal usages, with powerful rules to re-allow a call or a usage in places where it should be allowed.

33422.6M550](/packages/spaze-phpstan-disallowed-calls)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
