Skip to content

Instantly share code, notes, and snippets.

@Pierstoval
Last active April 21, 2020 09:13
Show Gist options
  • Save Pierstoval/b219bec7ad20749102b143f559ef507e to your computer and use it in GitHub Desktop.
Save Pierstoval/b219bec7ad20749102b143f559ef507e to your computer and use it in GitHub Desktop.

Native mocks versus PHPUnit mocks

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.

Benchmarks:

Native anonymous class (base time)

$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]);

Mockery (10% slower)

$repo = Mockery::mock(SubscriptionRepository::class);
$repo
    ->shouldReceive('hasSimilarActiveSubscriptions')
    ->with($subscription)
    ->once()
    ->andReturn(true)
;

// Tests ...

PHPUnit (45% slower)

$repo = $this->createMock(SubscriptionRepository::class);
$repo->expects(static::once())
    ->method('hasSimilarActiveSubscriptions')
    ->with($subscription)
    ->willReturn(true)
;

// Tests ...

Prophecy (2416% slower)

$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).

@Pierstoval
Copy link
Author

And by the way, thanks @jakzal for providing more benchmarks that confirm the initial theory 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment