DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป is a community of 963,274 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Kay Gosho
Kay Gosho

Posted on

Multibyte text and Laravel testing

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"}
Enter fullscreen mode Exit fullscreen mode

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',
        ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

(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('ๅคช้ƒŽ');
    }
}
Enter fullscreen mode Exit fullscreen mode

Reports the following error:

1) UserTest::testCanCreateUser
Failed asserting that '{"name":"\u592a\u90ce","sex":"male"}' contains "ๅคช้ƒŽ".
Enter fullscreen mode Exit fullscreen mode

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('ๅคช้ƒŽ'));
// ...
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)

๐ŸŒš Browsing with dark mode makes you a better developer.

It's a scientific fact.