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).
Interesting results!
You inspired me to make some blackfire profiles for similar tests (I'm on MacOS).
Repeat 1000
Repeat 100000