LoginSignup
2
1

More than 5 years have passed since last update.

Laravelで、日本語を含む assertDatabaseHas や assertSeeText がエスケープされてしまう時

Posted at

Laravel のテストを書いている時に、日本語(マルチバイト文字)はエスケープされてしまい、通るはずのテストが通らないという問題があった。

下記は通る。

<?php

use App\User;
use Tests\TestCase;

class UserTest extends TestCase
{
    public function testCanCreateUser()
    {
        User::create([
            'name' => '太郎',
            'gender' => 'male',
        ]);
        $this->assertDatabaseHas('users', [
            'name' => '太郎',
            'gender' => 'male',
        ]);
    }
}

(通らないケースとして挙げたのに、実際に動かしたらこれは通った・・・なぜだろう・・?)

通らないケースは、下記のように JSON API を叩くテストを書くときに、自動的に日本語がエスケープされてしまう時。

<?php

use App\User;
use Tests\TestCase;

class UserTest extends TestCase
{
    public function testUserProfileApi()
    {
        $user = User::create([
            'name' => '太郎',
            'sex' => 'male',
        ]);
        $this->actingAs($user)
            ->get('/api/me')
            ->assertSeeText('太郎');
    }
}

こうなる。

1) UserTest::testCanCreateUser
Failed asserting that '{"name":"\u592a\u90ce","sex":"male"}' contains "太郎".

確かにエスケープされてしまっている。

解決策

json_encode してあげれば良い。

<?php

use App\User;

//...
        $this->actingAs($user)
            ->get('/api/me')
            ->assertSeeText(json_encode('太郎');
// ...

utf8_encode でいいじゃん、と思うかもしれないが、自分の場合は駄目だった。この辺は php.ini で変わるのかもしれない。

他にも通らないことがあり(自分の場合はOAuth関連の処理を書いているときに通らなかった)、そういうときは e('太郎') を試してみると良いだろう。自分の場合はこれで解決した。

参考

中国語のサイトを含め探し回ったが、結局 Stack Overflow にあった。

こういうマルチバイト関連の問題について調べる時に、中国語に堪能だと便利だろうな・・・。
まあ漢字を読めるだけで日本人は有利だろう。

2
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
2
1