loading...

Multibyte text and Laravel testing

acro5piano profile image Kay Gosho ・2 min read

Problem

When I wrote test code in Laravel, I encountered a problem.

My API returns multibyte text.
By default, PHP's json_encode escapes multibyte text so my API returns like this:

curl localhost:8000/api/post/1

# Expected
{"title":"日本語"}

# Actual
{"title":"\u65e5\u672c\u8a9e"}

Laravel's $response->assertSeeText('日本語') does not work because it compares UTF-8 decoded string.

Example

This test passes:

<?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',
        ]);
    }
}

(TODO: In my case, I expected this test fail... but passed.)

This test, returns JSON API, fails:

<?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('太郎');
    }
}

Reports the following error:

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

Certainly, the text "太郎" is escaped.

Solution

Simply, assert the result using json_encode.

<?php

use App\User;

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

You might wonder why I don't use utf8_encode, but in my case it failed.
Maybe that depends on php.ini.

There are other failing cases related to multibyte, in my case writing OAuth testing using mock object.
Then you can try e('太郎'). My problem was solved by this.

We can avoid using multibyte string in testing, but sometimes we need to test such strings.

Refs

I researched a lot of websites, including Chinese websites like 思否, finally found in Stack Overflow as usual.

https://stackoverflow.com/questions/49570725/laravel-5-assertseetext-and-html-entities

I sometimes run into Chinese articles when solving these multibyte problem.
I cannot understand accurately but by Kanji I can guess what they say.

Discussion

pic
Editor guide