SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

基礎からはじめるReact入門

Reduxにおける同期的/非同期的なAction Creatorをテストする

基礎からはじめるReact入門 第12回

  • X ポスト
  • このエントリーをはてなブックマークに追加

通信を伴うAction Creatorのテスト

 非同期処理のテスト方法についてはここまで解説してきた通りですが、通信を伴うAction Creatorをテストするにあたっては、もう少し工夫が必要になります。これまで学んできたテストケースの作り方では対処ができない、次の2種類のテストを実施できるようにしなければいけません。

  • 外部環境とのデータ授受で得られたデータを条件に持つテスト
  • 引数として渡された値を検査するテスト

 それぞれの具体的な内容を解説します。

外部環境とのデータ授受で得られたデータを条件に持つテスト

 テストケースを作成するにあたって、常に関数を実行する条件は同じであることが望ましいです。テストケースの内部に記述したデータは、テストを実行するごとにリセットされるため、望ましい状態であるといえるでしょう。しかし、関数が内部でサーバーやデータベースにアクセスしている場合、前回テストを実行したときの結果が残ってしまったり、同じテストを実行している同僚の実行結果が残っていたりして、同じデータを使えない状況が発生します。

 非同期のAction Creatorは、内部でサーバーのAPIなどを呼び出していることがあります。一般的に、自動テストを作成する際には、テストケースの中ですべての条件を記述できるのが好ましいです。しかし、サーバーにアクセスしてしまうと、サーバー側の状態に応じてテスト結果が変わってしまう恐れがあります。これは、あまりうれしい状況ではありません。

 こういった場合に取る対策としては、大別すると次の2つがあります。

  1. テストケースごとに通信処理を偽装して、固定の値しか返ってこないようにする
  2. テストケースごとにテスト用のAPIサーバーを起動して、固定の値しか返ってこないようにする

 後者は大掛かりになってしまうので、本記事では前者の方針を採ることにします。偽装とはいっても、特殊なツールを使うわけではありません。通信用のモジュールに定義されている関数を、テストケースの中で上書きするだけです(リスト9)。

[リスト9]APIクライアントを上書きする例
import ApiClient from "../api/ApiClient";

// fetchPosts関数が固定の結果しか返さないようにする
ApiClient.fetchPosts = () => Promise.resolve([
  { id: 1, name: "なかがわ", age: "thirties", body: "なかがわです" },
  { id: 2, name: "たなか", age: "fourties", body: "たなかです" },
  { id: 3, name: "すずき", age: "teen", body: "すずきです" },
]);

 テストケースの序盤にリスト9の処理を実行しておけば、その後にAction Creatorを実行した際にも内部では偽装した処理のほうが実行されます。これにより、常に意図した条件下でテストが実施されるようになります。

引数として渡された値を検査するテスト

 テストケースの主な目的は、処理の結果としてどんな値が生まれたのかを検査することです。これまで学んできた範囲では、関数の戻り値やPromiseの結果を検査していました。しかし、リスト10のような、非同期なAction Creatorにありがちな通信処理の場合はどうでしょうか。

[リスト10]引数を検査したくなる処理の例
function doGet(a, b, dispatch) {
  fetch(`https://example.com?a=${a}&b=${b}`)
  .then(response => {
    dispatch({ type: "HOGE", payload: response }); // (1)
  });
}

 ここで処理結果として検査したいのは、(1)でdispatch関数の引数として渡されたオブジェクトです。Reduxの性質上、dispatch関数を実行することでしかアプリケーションの状態を更新することができないので、dispatch関数に渡すActionオブジェクトをAction Creatorの成果、つまり検査対象として扱っても問題ないだろう、といった考え方です。

 さて、dispatch関数の引数に何が渡されたのかをチェックしたいわけですが、幸い、Jestにはこういった用途に最適な機能が用意されています。**モック関数**と呼ばれる機能です。次節で解説します。

Jestのモック関数機能について

 前述の通り、Jestには関数呼び出しを記録・検査するための仕組みとして「モック関数(Mock Functions)」と呼ばれる機能が用意されています。詳しいドキュメントはこちらのリンクをご覧ください。

 本記事では、引数の調べ方のみを解説します。リスト11が実行例です。

[リスト11]モック関数の使用例
function hoge(callback) {
  callback(1); // (a)
  callback(2, 3); // (b)
  callback(4); // (c)
}

test("sample", () => {
  const mockFn = jest.fn(); // (1)
  hoge(mockFn); // (2)
  const calls = mockFn.mock.calls; // (3)
  expect(calls[0]).toEqual([1]); // (a)で渡した引数
  expect(calls[1]).toEqual([2, 3]); // (b)で渡した引数
  expect(calls[2]).toEqual([4]); // (c)で渡した引数
});

 まず、グローバル変数jestから、jest.fn()を呼び出すことでモック関数オブジェクトを作り出します(1)。これをdispatch等の代わりに引数としてテスト対象の関数に渡す(2)ことで、内部でどのような呼び出され方をしているのかを記録できます。テスト対象の関数が実行された後、モック関数オブジェクトの.mock.callsプロパティ(3)には、内部でどんな引数が渡されたのかが2次元配列で記録されています。このcalls内のデータを検査することで、内部での処理結果をうかがい知ることができます。

次のページ
掲示板アプリのAction Creatorをテストする

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
基礎からはじめるReact入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/11044 2018/09/07 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング