LoginSignup
6
2

More than 5 years have passed since last update.

Laravel の Real Time Facade で簡単にテストする

Posted at

概要

Real Time Facade が便利だったけどあまりそれについての tips とかがなかったので書いてみる.
テストしにくいような処理を Real Time Facade を用いてサクッとテストかけるよっていう紹介.

準備

Qiita の投稿一覧を API で取得して、そのタイトルを一覧するような処理を書く.
多分 QiitaController みたいな感じでこうなる

# Controller 作成
php artisan make:controller QiitaController

コントローラーの中身はこんな感じ

<?php // app/Http/Controllers/QiitaController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class QiitaController extends Controller
{
    public function index(Request $request)
    {
        $page = $request->input('page', 1);
        $perPage = $request->input('per_page', 20);
        $jsonResponse = file_get_contents("https://qiita.com/api/v2/items?page={$page}&per_page={$perPage}");
        $response = json_decode($jsonResponse, true);

        $str = '<ul>';
        foreach ($response as $item) {
            $str .= '<li>' . $item['title'] . '</li>';
        }
        $str .= '</ul>';
        return $str;
    }
}

テスト書いてみる

php artisan make:test QiitaControllerTest

多分中身はこんな感じ

<?php

namespace Tests\Feature;

use Tests\TestCase;

class QiitaControllerTest extends TestCase
{
    public function testIndex()
    {
        $response = $this->get('/qiita');
        $response->assertStatus(200);
    }
}

とりあえずこれでテストは通る。
これでもいいけど、これはQiitaのサイトのステータスやネットワークの状態によってテストの結果が変わってしまう。
もう少しかっこよくしたい。

処理のまとまりを切り出す

方針としては、API取得の部分を関数に切り出すと良さそう。
仮に QiitaApi というクラスに切り出してみよう。

<?php // QiitaApi

namespace App;

class QiitaApi
{
    public function getItems($page = 1, $perPage = 20)
    {
        $jsonResponse = file_get_contents("https://qiita.com/api/v2/items?page={$page}&per_page={$perPage}");
        $response = json_decode($jsonResponse, true);
        return $response;
    }
}

こんな感じ

このクラスを利用したコントローラーは下記のように修正する

<?php

namespace App\Http\Controllers;

use App\QiitaApi;
use Illuminate\Http\Request;

class QiitaController extends Controller
{
    public function index(Request $request)
    {
        $api = new QiitaApi();
        $page = $request->input('page', 1);
        $perPage = $request->input('per_page', 20);
        $response = $api->getItems($page, $perPage);

        $str = '<ul>';
        foreach ($response as $item) {
            $str .= '<li>' . $item['title'] . '</li>';
        }
        $str .= '</ul>';
        return $str;
    }
}

Facade を導入する

少し良くなったけど、まだテストし辛いのは変わらない。
ここで本題の Read Time Facade を導入して書いてみる。
5.4から導入された Real Time Facade は、use する namespace のアタマに Facades とつければそのクラスを Facade として利用できるというものらしい。
この黒魔術は localdisk さんが記事を書いているのでそちらを参照されたいhttp://tech.innovator.jp.net/entry/2017/08/29/135714

<?php

namespace App\Http\Controllers;

use Facades\App\QiitaApi;
use Illuminate\Http\Request;

class QiitaController extends Controller
{
    public function index(Request $request)
    {
        $page = $request->input('page', 1);
        $perPage = $request->input('per_page', 20);
        $response = QiitaApi::getItems($page, $perPage);

        $str = '<ul>';
        foreach ($response as $item) {
            $str .= '<li>' . $item['title'] . '</li>';
        }
        $str .= '</ul>';
        return $str;
    }
}

テストでモックを使う

さて、ここまでできたらAPI取得をQiitaのステータスやネットワークの状態に依存しないように QiitaApi クラスをモックしてみよう。
テストは下記のように書くことができる。

<?php

namespace Tests\Feature;

use Facades\App\QiitaApi;
use Tests\TestCase;

class QiitaControllerTest extends TestCase
{
    public function testIndex()
    {
        QiitaApi::shouldReceive('getItems')
            ->withAnyArgs()
            ->once()
            ->andReturn([
                ['title' => 'hoge'],
                ['title' => 'fuga'],
                ['title' => 'piyo'],
            ]);
        $response = $this->get('/qiita');
        $response->assertStatus(200);
        $response->assertSeeText('hoge');
        $response->assertSeeText('fuga');
        $response->assertSeeText('piyo');
    }
}

このように Real Time Facade はそれ自体がモックを簡単にできるようにされているので、どのメソッドがコールされ、何を返すかを指定することができる。(端折ったけど、実際のレスポンスをフィクスチャとして保持して、それを返すようにしたほうがよさそう)

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