📝

PHPUnit 10 で $this->prophesize メソッドがビルトインではなくなります

2021/05/07に公開

PHPUnit 4.5.0 から、 Prophecy と呼ばれるモックライブラリがビルトインされ、簡単に利用出来るようになっています。
これは PHPUnit 自体に内包されているモック実装とは別に利用できるものです。使っているプロジェクトもそこそこあるんじゃないかなと思います。

しかし、 PHPUnit の成長に伴って、 PHPUnit と Prophecy の composer での依存関係が循環してしまうような状態となり、アップグレードが難しい状態になってしまいました。
それを解消するため、 PHPUnit 自体が Prophecy を依存しないようにする、というのが 下記の issue で議論されていました。
https://github.com/sebastianbergmann/phpunit/issues/4141

$this->prophesize をテストコード中で利用している場合、 PHPUnit 9 で DEPRECATED のメッセージが出るようになり、 10 で完全に削除されます。

もちろんこれを回避する方法が紹介されています。 composer require --dev phpspec/prophecy-phpunit として prophecy-phpunit ライブラリをアプリケーション側の依存として導入し、追加された Prophecy\PhpUnit\ProphecyTrait を TestCase クラスで use するだけです。

<?php

namespace App;

use App\Entity\User;
use App\Security\Hasher;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;

/**
 * @coversDefaultClass \App\Entity\User
 */
class UserTest extends TestCase
{
    use ProphecyTrait; // prophecy を利用する場合はこれを追加する

    /**
     * @covers ::__construct
     * @covers ::setPassword
     * @covers ::getPassword
     */
    public function testPasswordHashing()
    {
        $hasher = $this->prophesize(Hasher::class);
        $user   = new User($hasher->reveal());

        $hasher->generateHash($user, 'qwerty')->willReturn('hashed_pass');

        $user->setPassword('qwerty');

        $this->assertEquals('hashed_pass', $user->getPassword());
    }
}

Prophecy に依存したテストケースそれぞれに入れてもいいですし、下記のようにベースクラスを用意してそこで use することも可能です。

<?php

namespace App;

use PHPUnit\Framework\TestCase as BaseTestCase;
use Prophecy\PhpUnit\ProphecyTrait;

abstract class TestCase extends BaseTestCase
{
    use ProphecyTrait;
}

PHPUnit は dev 依存だからという所で結構大き目の破壊的変更をメジャーアップデートごとにやっているので、適切にバージョンアップ出来るように対応していきましょう。

Discussion