Mock type | Tests duration |
---|---|
Native mocks | 160.10 seconds |
Mockery | 177.01 seconds (+10%) |
PHPUnit mocks | 232.29 seconds (+45%) |
Prophecy | 3868.80 seconds (+2416%) |
Benchmarked on the exact same Windows machine, with PHP 7.3.7, PHPUnit 8.2.5, inside a Docker container, testing consisting on executing the same test 400k times.
I did not show native classes here, as we only focus on PHPUnit's system.
$repo = new class() extends SubscriptionRepository {
public $executions = [];
public function __construct()
{
// Don't call parent constructor in case it needs dependencies
}
public function hasSimilarActiveSubscriptions(Subscription $subscription): bool
{
// Only mock methods that have to be used during the test
$this->executions[] = $subscription;
return true;
}
};
// Tests ...
static::assertCount(1, $repo->executions);
static::assertSame($subscription, $repo->executions[0]);
$repo = Mockery::mock(SubscriptionRepository::class);
$repo
->shouldReceive('hasSimilarActiveSubscriptions')
->with($subscription)
->once()
->andReturn(true)
;
// Tests ...
$repo = $this->createMock(SubscriptionRepository::class);
$repo->expects(static::once())
->method('hasSimilarActiveSubscriptions')
->with($subscription)
->willReturn(true)
;
// Tests ...
$repo = $this->prophesize(SubscriptionRepository::class);
$repo
->hasSimilarActiveSubscriptions($subscription)
->shouldBeCalledOnce()
->willReturn(true)
;
// Don't forget that "$repo" must be injected using "$repo->reveal()"
// Tests ...
I think it is worth mentioning that I could only run Prophecy tests with batches of 25k tests instead of 400k. More was leading to segfaults. Therefore, the time is an average (but significantly slower anyway).
And by the way, thanks @jakzal for providing more benchmarks that confirm the initial theory 👍