3
1

More than 1 year has passed since last update.

【PHPUnit】assertSameとassertEqualsを正しく使い分ける

Last updated at Posted at 2023-01-18

はじめに

今回の記事はassertSameとassertEqualsの使い分けについてです。何気なくassertSameを使用していて、意図しないエラーに遭遇したので、忘れないよう記事にします

状況と発生したエラー内容

今回のエラーは下記テストを実行した際に出力されました。ユーザーリポジトリのfindById(ユーザーIDを指定すると対象のユーザーを取得できるメソッド)のテストです。存在するユーザーIDを渡すとユーザーを1件取得できることを確認しています

また、assertUserメソッドでは、オブジェクトの属性値が期待するオブジェクトと、実際のオブジェクトで等しいかどうかを評価しています

    public function test_存在するユーザーIDを渡すとユーザーを1件取得できること(): void
    {
        // given
        $expectedUser = $this->user;

        // when
        $actualUser = $this->userRepository->findById($expectedUser->getUserId());

        // then
        $this->assertUser($expectedUser, $actualUser);
    }

    private function assertUser(Uesr $expectedUser, Uesr $actualUser): void
    {
        $this->assertSame($expectedUser->getUserId(), $actualUser->getUserId());
        $this->assertSame($expectedUser->getName(), $actualUser->getName());
        $this->assertSame($expectedUser->getEmail(), $actualUser->getEmail());
    }

実行すると、以下のようなエラーが出力されました

実行結果:

Failed asserting that two variables reference the same object.

Time: 00:01.875, Memory: 22.00 MB

FAILURES!
ERROR: 1

なぜこのようなエラーが起こったのでしょうか?

assertSame は「オブジェクトの属性値が同じ」という意味ではない

assertSameは 「オブジェクト同士を比較する場合、その2つのオブジェクトが同じオブジェクトを参照しているかどうか」 ということを評価します

なので、上記のコードは同じオブジェクトを参照しているわけではないので、エラーが表示されているのです

詳しくはこちらに記載してあります
https://phpunit.de/manual/3.6/ja/writing-tests-for-phpunit.html

では、オブジェクトの属性値を比較する際はどのメソッドを使用すればいいのか?

オブジェクトの属性値を比較する際は assertEquals を使う

オブジェクトの属性値を比較する際は assertEquals を使用します。このメソッドは2 つのオブジェクト $expected$actual が同じ属性値を持たない場合にエラーを出力します

なので、下記コードのようにassertSameをasssertEqualsに変更すると正しく評価されるようになります

    public function test_存在するユーザーIDを渡すとユーザーを1件取得できること(): void
    {
        // given
        $expectedUser = $this->user;

        // when
        $actualUser = $this->userRepository->findById($expectedUser->getUserId());

        // then
        $this->assertUser($expectedUser, $actualUser);
    }

    private function assertUser(Uesr $expectedUser, Uesr $actualUser): void
    {
-       $this->assertSame($expectedUser->getUserId(), $actualUser->getUserId());
-       $this->assertSame($expectedUser->getName(), $actualUser->getName());
-       $this->assertSame($expectedUser->getEmail(), $actualUser->getEmail());
+       $this->assertEquals($expectedUser->getUserId(), $actualUser->getUserId());
+       $this->assertEquals($expectedUser->getName(), $actualUser->getName());
+       $this->assertEquals($expectedUser->getEmail(), $actualUser->getEmail());
    }

一応実行結果としては、以下の通りです

実行結果:

Testing started at 18:33 ...

Time: 00:01.734, Memory: 22.00 MB

OK (1 test, 1 assertion)

おわりに

「assertSameとassertEqualsの使い分け」についての説明は以上です。何かご指摘等あればコメント等で教えていただけると大変嬉しいです

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1