kikukawa's diary

都内で活動するシステムエンジニアが書いてます。 興味を持った技術やハマったポイント、自分用メモをつけてます。 最近はweb中心

phpunit8のwarning対応

phpunit8を使っているとphpunit9でなくなるメソッドなどのwarningが発生します。
その対処方法いくつか備忘録として残しておきます。

assertArraySubset

結構重宝していたのでなくなるのは辛いメソッドです。
代替手段としては、 https://packagist.org/packages/dms/phpunit-arraysubset-asserts があります。
本家phpunitのissue でも紹介されているのでメンテナンスの心配は少なそうです。

phpunit8では、 v0.1系を使う必要があります。 執筆時点での最新は v0.2系です。

assertAttributeSame

こちらは代替となるパッケージがありませんでしたので自作になります。
本家はclassとobject両方に対応していましたが、下記はobjectのみです。
また、objectのプロパティにアクセスするという簡単なことが実はいろいろ考えると複雑な処理になるので
symfony/property-access を使って楽をしてます。

use PHPUnit\Framework\InvalidArgumentException;
use Symfony\Component\PropertyAccess\PropertyAccess;

trait Test_Concern_AssertObjectAttribute
{
    /**
     * @param $expected
     * @param string $actualAttributeName
     * @param $actualObject
     * @param string $message
     */
    public function assertObjectAttribute($expected, string $actualAttributeName, $actualObject, string $message = '')
    {

        if (!is_string($actualAttributeName)) {
            throw InvalidArgumentException::create(2, 'attribute name');
        }
        if (!is_object($actualObject)) {
            throw InvalidArgumentException::create(3, 'object');
        }
        $propertyAccessor = PropertyAccess::createPropertyAccessorBuilder()
        ->disableExceptionOnInvalidPropertyPath()
        ->getPropertyAccessor();

        $prop = $propertyAccessor->getValue($actualObject, $actualAttributeName);
        /** @noinspection PhpUndefinedMethodInspection */
        self::assertSame(
            $expected,
            $prop,
            $message
        );
    }
}

assertContains

代わりに assertStringContainsString を使います。

expectException

アノテーションを使ったExceptionのアサーションではなく、メソッド形式に変更します。
Exceptionを発生させる処理の前に、expectExceptionなどを呼び出しておくだけです。

/**
 * @expectedException ErrorException
 * @expectedExceptionMessage process is timeout.
 */
public function test_foo()
{
    trigger_exception();
}
public function test_foo()
{
    self::expectException(ErrorException::class);
    self::expectExceptionMessage('process is timeout.');
    trigger_exception();
)

This test did not perform any assertions

phpunitアサーションが一つもないテストに表示されます。
dbunitやmockeryなど別の手段でアサーションしている場合は、 @doesNotPerformAssertions でリスキーではないとマークして対処できます。

参考