他のツールとの比較
Mirage を他の API モックツールやアプローチと比較してみましょう。
JSON Server
JSON Server は、Node.js で即座に REST API を作成できる人気のツールです。
Mirage と JSON Server の主な違いは、Mirage が本番 API の正確な形状をモックするように設計されているのに対し、JSON Server はその規約とデータベースファイルの内容に基づいて特定の API 形式を作成することです。いくつかの構成オプションはありますが、JSON Server を使用して本番 API のルートとペイロードを完全に複製することは難しく、場合によっては不可能なため、アプリケーションコードは本番環境のような環境で記述およびテストされません。
Mirage の哲学は、HTTP バウンダリにとどまり、アプリケーションコードに影響を与えないことです。本番 API が Mirage の構成を決定し、その逆ではありません。
Mirage のその他の利点
Mirage はフロントエンドコードと並んでブラウザで実行されるため、開発環境での実行と CI サーバーでのテストの実行が簡単になります。追加のプロセスを管理またはリセットする必要はありません。
Mirage は ORM を介して完全な参照整合性をサポートし、アプリがデータを変更しても、すべてのリソースの外部キーを管理します。
Mirage はブラウザのリロードごとに状態をリセットします。これは両刃の剣ですが、開発とテストには最適な場合が多いです。(
localStorage
を使用して、Mirage に一時的な永続性を追加することもできます。)Mirage は GraphQL やその他の API 形式と連携します。
JSON Server は Mirage よりもいくつかの利点があります。
実際のサーバーであるため、開発ツールのネットワークタブや Paw や curl などの HTTP ツールを使用してリクエストを送信し、レスポンスを検査できます。
Node.js と Express で記述されているため、Node.js エコシステムの全機能を利用できます。
すぐに使えるフィルタリングとソートの実装があります(ただし、本番 API と一致しない可能性が高いです)。
MSW
MSW は、ブラウザまたは Node.js で実行できるモックライブラリです。
Mirage と MSW はどちらもフロントエンドコードと並んでクライアントで実行されますが、主な違いは、MSW がネットワークリクエストをインターセプトするために Service Worker を使用することに対し、Mirage はPretender.js を使用し、window.fetch
と window.XMLHttpRequest
をモンキーパッチすることによって機能します。
Service Workerを使用する主な利点は、リクエストがDevToolsの「Network」タブに表示されることです。ブラウザの観点からは、これは実際HTTPリクエストです。これにより、MSWからのレスポンスの検証における開発者エクスペリエンスが、実際のサーバーサイドAPIとのやり取りにより近づきます。
MSWのその他の利点
Node.js上で動作するため、モックをブラウザ以外のNode.js環境で共有できます。MirageもNode.js上で動作しますが、ブラウザのような環境(つまり、
jsdom
のようなものがある環境、Jestなどのツールが設定してくれます)でのみ動作します。現時点では、MirageはReactアプリのサーバーサイドAPIリクエストをモックアウトするために使用することはできません。GraphQLをモックアウトするためのファーストパーティAPIがあります。(MirageでもGraphQLをモックアウトできますが、現在ライブラリにはそれを支援するファーストパーティAPIはありません。)
MirageがMSWと比較して持つ主な利点は、低レベルなインターセプタ機能のみを提供する他のライブラリと比較して持つ利点と同様です。MSWの主なAPIは、リクエストを受け取り、レスポンスを記述できるルートハンドラーです。Mirageは同様のルートハンドラーAPIを提供しますが、データベース、リレーションシップのサポート、さまざまなデータシナリオの作成を容易にするファクトリ、JSONペイロードの形状を本番APIに合わせるためのシリアライザレイヤー、テスト内でデータベースの状態と変更を簡単にアサートするためのサーバーインスタンスも備えています。
インターセプタ(Mirage、MSW、Pretender、fetch-mockなど)を接続した後、本番APIの動作を忠実に再現する方法でAPIルートを実装することが、モックコードの複雑さのほとんどが存在する場所です。そのため、インターセプタ機能のみを提供するライブラリは、この作業をユーザーに任せています。これは、GraphQLとREST APIの両方で当てはまります。
Mirage のその他の利点
Mirageは設定が少し簡単です。フロントエンドコードと一緒に1つのインポートだけです。
import { createServer } from "miragejs" let server = createServer() server.get("/api/movies", () => ["Interstellar", "Inception"])
MSWには追加のステップが1つ必要です。プロジェクトのpublicディレクトリにService Workerファイルを作成する必要があります。これは、本番ビルドから削除したい場合もあります。
Mirageはテストのために構築されており、開発データとテストデータのシード、ルートハンドラーを書き直すことなくテスト内で直接さまざまなデータシナリオを作成する機能などの概念を備えています。
MSWは優れたライブラリであり、Service Workerの概念はいつかMirageにも取り込まれるかもしれませんが、すべてのエンドポイントを手動でモックするのは面倒で、時間の経過とともに保守が難しくなります。モックに関するいくつかの規約を設け、JavaScriptアプリが読み書きリクエストを行う際にデータの参照整合性を維持することが、Mirageが最初に作成された理由です。
その他の低レベルモックライブラリ
特定のエンドポイントの静的モックを定義するために、単独で使用されることが多い(通常はテスト)低レベルのモックツールがあります。(PretenderおよびFakeRestなど)。(実際、Mirageはインターセプタとして内部的にPretenderを使用しています!)
これらのツールとMirageの最大の相違点は、Mirageは本番APIサーバー全体を忠実に再現するように設計されているため、アプリは本番環境でネットワークと通信する場合とまったく同じ方法でMirageと通信できることです。Mirageのデータレイヤーとシリアライザレイヤーによってこれが可能になります。すべてのエンドポイントを手動でモックするのは面倒で、更新を維持することが難しく、Mirageの存在につながったものです。
GraphQLクエリモック
GraphQLで作業する際には、Apollo MockedProviderなどのパッケージを使用して、クエリレベルでモックするのが一般的です。これは低レベルのRESTモックライブラリと同様の問題があり、複数のクエリをモックする場合(つまり、アプリがmovie
を作成し、その後allMovies
クエリを実行しますが、新しい映画がありません)、データの参照整合性を維持することが非常に困難になる可能性があります。
これらの同じような問題点が、リソースレベルではなくクエリレベルで動作するMirageの作成につながりました。
Cypressルートモック
Cypressには、テスト中にバックエンドをスタブアウトできるcy.route() API
が含まれています。
Cypressのネットワークモックは静的フィクスチャ(通常はJSONファイル)に基づいているため、CRUD操作全体のリソースの一貫性を確保するためにデータベースを使用しない他のツールと同様の問題が発生します。
Cypressには、テストでスタブを明示的に待機することを推奨するエイリアスAPIもあります。
cy.get("#autocomplete").type("Book")
// Wait for the request + response
cy.wait("@getSearch")
cy.get("#results").should("contain", "Book 1")
Mirageの観点から、このテストには通常混合すべきではない2つの異なる抽象化レベルが含まれています。1つは実際のエンドユーザーの視点から記述された、可視的なUI要素とユーザーインタラクション(type('Book')
と(#results).should('contain', 'Book 1')
など)、もう1つはHTTPエイリアス(wait('@getSearch')
)であり、これはこのページの実装の詳細であり、エンドユーザーには実際には表示されません。
Mirageでは、UIテストを単一の抽象化レベルで記述することを推奨しています。通常はエンドユーザーの実世界の動作に焦点を当てています。HTTPレスポンスを待機する場合、リクエストが保留中であるか完了したかを示すUIの一部を待機するのが最善です。ページを動作させている特定のHTTPリクエストのような実装の詳細ではなく、その方が良いです。このため、CypressのエイリアスAPIは、コードの再ファクタリングを困難にする壊れやすいテストにつながると考えています。
これらの違いは、CypressのHTTPモックレイヤーに関するものですが、全体として、私たちはCypressの大ファンです!そして、Mirageは、Cypressテストコードと一緒にAPIモックレイヤーとして使用する場合に最適です。実際、CypressアプリにMirageを設定する方法に関するクイックスタートガイドもあります!
その他の違いとしては、CypressのAPIモックは通常開発で共有されないという事実があります。これは、Mirageの中核となる価値提案の大きな部分を占めています。さらに、この記事を書いている時点では、Cypressはfetch
リクエストをインターセプトしませんが、Mirageはインターセプトします。
ここにリストされていない他のツールとのMirageの比較に興味がある場合は、issueを作成してお気軽にお問い合わせください!