Laratablesを使ったユニットテストがPHP8.2にしたら失敗するのを解決した話

経緯

業務で使っているLaravelが6で古いため9まで上げることになり、それの担当を任された。

Laravel9に上げるにあたって、PHPのバージョンも次の通り更新する必要があります。

更新前 更新後
PHP 7.3 8.2
Laravel 6.x 9.x

Laratablesについて

Laravelから取得したデータをDataTableで簡単に表示させるためのパッケージ。 実はこのDataTableというのが重要です。

Laratablesはgithubリポジトリが公開されていますが、今では開発されてなさそう?

起こったこと

Laravelは公式のアップデートガイドに沿って7, 8, 9と順々に更新していきます。 更新してはテストを繰り返し上げていったのですが、9に上げたときに今まで動いていたテストが動かなくなりました。

Laravel9からは、更新前のPHP7.3に対応していないので、 Laravel9に上げるタイミングに合わせてPHPも8.2に更新しました。

更新後にテストを実行すると以下のようなエラー文が出力されました。

ErrorException: Trying to access array offset on value of type null

nullに対してアクセスをしてしまっているようです。発生しているのはvendor配下のLaratablesのパッケージ。

対応

問題のコード

渡すパラメータを配列でまとめ、テストしたいルーティングを呼び出します。

// getリクエストのパラメータリスト
$params = [
  'param1' => 'パラメータ1',
  'param2' => 'パラメータ2'
];

// テストする処理を呼び出すルーティング(Laratablesでデータを返す)
$response = $this->get(
  route('sample.route.name'),
  $params
);

修正したコード

リクエストパラメータに、Laratablesの処理が使用するパラメータを追加する($laratables_params) その後、検証したいIDと連結して一つのパラメータリストとしている。

$laratables_paramsで定義されているパラメータは、DataTableで使用されるもので、 Laratablesのドキュメントにあるクライアント側の処理で送られる時に付与されます。

テストの時はこのパラメータが送られていなかったので、Laratablesの処理が参照できず、エラーになっていました。

// Laratablesで使用されるパラメータ
$laratables_params = [
  'draw' => '1',
  'columns' => [
    [
      'data' => '0',
      'name' => 'hoge',
      'searchable' => 'true',
      'orderable' => 'true',
      'search' => [
        'value' => '',
        'regex' => 'false'
      ]
    ]
  ],
  'order' => [
    [
      'column' => '0',
      'dir' => 'asc'
    ]
  ],
  'start' => '0',
  'length' => '10',
  'search' => [
    'value' => '',
    'regex' => 'false'
  ]
];

// 検証したいID
$test_params = [
  'param1' => 'パラメータ1',
  'param2' => 'パラメータ2'
];

// 一つにまとめる
$request_params = [
  ...$laratable_params,
  ...$test_params
];

$response = $this->get(
  route('sample.route.name'),
  $request_params
);

まとめ

テストの時にも、DataTableで使用されるパラメータを付与することで対応できます。 項目数が結構多いので、定数クラスとして定義しておいて必要な時に参照するのが良さそうです。