このライブラリはXMLHttpRequestのモックであり、 XMLHttpRequestとの対話をシミュレートするための単純なインターフェイスを提供します。これは、テスト用のXMLHttpRequestのドロップイン代替品です。
このライブラリはXMLHttpRequestインターフェイスを実装し、実際のネットワーク リクエストを使用せずに、XMLHTTPRequest 仕様で指定されているようにリクエストとイベントを処理します。模擬リクエストには次の 3 つの方法で応答できます。
模擬応答メソッドを使用して、応答をシミュレートし、進行状況、エラー、その他のインタラクションをアップロードできます。これらは、イベントの発行やXMLHttpRequestのreadystateプロパティの変更などの下位レベルの処理を自動的に処理します。
MockXhrリクエストにプログラムで応答するtimeout属性とリクエストのタイムアウトMockXhrライフサイクル フックの使用MockXhrServerクラスMockXhrServerセットアップMockXhrクラスMockXhrライフサイクル フックMockXhrRequestクラスnewMockXhr()newServer()XMLHttpRequest機能npm (ノードパッケージマネージャー) 経由
$ npm install mock-xmlhttprequest
import { newServer } from 'mock-xmlhttprequest' ;
import { functionToTest } from '../src/SomethingToTest' ;
// Adapt based on your testing framework. This example uses Mocha and Chai's syntax.
it ( 'should produce a success response' , async ( ) => {
const server = newServer ( {
get : [ '/my/url' , {
// status: 200 is the default
headers : { 'Content-Type' : 'application/json' } ,
body : '{ "message": "Success!" }' ,
} ] ,
} ) ;
try {
// Installs the server's XMLHttpRequest mock in the "global" context.
// After this, "new XMLHttpRequest()" creates a mock request to which the server replies.
server . install ( /* optional context; defaults to globalThis */ ) ;
// Do something that send()s an XMLHttpRequest to '/my/url' and returns a Promise
// that resolves to the parsed JSON response
const result = await functionToTest ( ) ;
assert . equal ( result . message , 'Success!' ) ;
} finally {
// Restore the original XMLHttpRequest
server . remove ( ) ;
}
} ) ; XMLHttpRequestモック クラスはMockXhrです。これはXMLHttpRequestと同じインターフェイスを公開し、 XMLHttpRequestを使用するテスト コードのドロップイン置き換えです。
MockXhrインスタンスの動作を制御するには 2 つのオプションがあります。
XMLHttpRequestライフサイクル フック。モック サーバーが提供する機能を使用せずにリクエストをさらに制御する必要がある場合は、これを使用します。MockXhrServerクラスはモック サーバーを実装します。 newServerを使用してMockXhrServer作成します。 MockXhrServer MockXhrリクエストに自動的に応答し、テストの作成を簡単にします。
MockXhrServer使用するテストの基本構造は次のとおりです。
import { newServer } from 'mock-xmlhttprequest' ;
const server = newServer ( /* routes */ ) ;
try {
server . install ( /* optional context; defaults to globalThis */ ) ;
// Test your code that creates XMLHttpRequests
} finally {
// Reverts server.install() at the end of the test.
// Only do this after the test case has finished creating XMLHttpRequests.
server . remove ( ) ;
}コードでXMLHttpRequestの代わりにMockXhrクラスを使用するには、2 つの方法があります。これにより、 MockXhrServerリクエストに応答できるようになります。
install()を使用して、 XMLHttpRequestクラスをサーバーのMockXhrクラスにグローバルに置き換えます。テスト ケースの最後に、 remove()呼び出して元の状態に戻します。XMLHttpRequestのインスタンスの作成方法を構成できる場合は、次のMockXhrServerプロパティのいずれかでMockXhrクラスを直接使用します。xhrFactoryはMockXhrインスタンスを作成する関数です。MockXhr xhrFactoryによって作成されるインスタンスのクラスです。このコードは、 xhrFactoryの使用法を示しています。
import { newServer } from 'mock-xmlhttprequest' ;
const server = newServer ( /* routes */ ) ;
const savedFactory = MyClass . xhrFactory ;
try {
MyClass . xhrFactory = server . xhrFactory ;
// Test code that creates XMLHttpRequests through MyClass.xhrFactory()
} finally {
// Only do this after the test case has finished creating XMLHttpRequests.
MyClass . xhrFactory = savedFactory ;
}ルートは、 MockXhrServerがMockXhrリクエストにどのように応答するかを定義します。これらには 3 つの部分があります。
MockXhrリクエストを送信すると、 MockXhrServerリクエストのメソッドと URL に一致する最初のルートを検索します。次に、ルートのリクエスト ハンドラーで応答します。デフォルトのリクエスト ハンドラーを設定することもできます。リクエスト ハンドラーは、宣言またはプログラムによって定義されます。
デフォルトでは、リクエストのtimeout属性がゼロ以外の値に設定されており、 MockXhrServerリクエストに応答しない場合、最終的にタイムアウトになります。
MockXhrServerにルートを追加するには 2 つの方法があります。
newServerのroutes引数。MockXhrServerメソッド。 MockXhrServer受信したすべてのMockXhrリクエストをリクエスト ログに記録します。これを使用して、コードが送信するXMLHttpRequestリクエストを検証します。
MockXhrServer 、リクエスト (アップロード) および応答 (ダウンロード) の進行状況イベントを自動的に生成できます。これはデフォルトでは無効になっています。これを有効にするには、 progressRateフィールドを使用します。
Functionタイプのリクエスト ハンドラーを使用してプログラムでMockXhrリクエストに応答する場合、進行状況イベントを生成することもできます。
MockXhrリクエストに対する応答は非同期です。これは、実際のXMLHttpRequestリクエストがどのように動作するかを再現します。したがって、ほとんどの場合、テスト フレームワークの非同期テスト サポートを使用する必要があります。たとえば、Mocha テスト フレームワークの関連ドキュメントはここにあります。
onSendライフサイクル フックは、 MockXhrリクエストに応答するために必要です。モックサーバーはこれを自動的に処理します。もう 1 つのオプションは、 MockXhrライフサイクル フックを直接使用することです。どちらの場合も、 onSendライフサイクル フックは、 XMLHttpRequest.send()を呼び出す実行コンテキストが完了またはクリアされた後に実行されます。内部的には、このライブラリはすぐに解決されるPromiseを使用して空のコールスタックを取得します。
MockXhrリクエストにプログラムで応答するリクエストに応答するためのMockXhrメソッドとプロパティがいくつかあります。これらのメソッドでは、次のような対話が可能になります。
詳細については、「模擬応答メソッド」セクションを参照してください。
timeout属性とリクエストのタイムアウトデフォルトでは、コード内でXMLHttpRequestのtimeout属性を設定すると、 MockXhrリクエストは指定された遅延の後に自動的にタイムアウトになります。これにより、 timeoutイベントが発行され、仕様に記載されているようにリクエストがキャンセルされます。
コードがタイムアウトをどのように処理するかを時間の経過に依存してテストすると、一般にテストが脆弱になり、デバッグが困難になります。代わりに、 setRequestTimeout()を使用してプログラムでタイムアウトをトリガーできます。
次のいずれかのオプションを使用して、自動リクエスト タイムアウトを無効にします。
MockXhrServerでdisableTimeout()を呼び出します。これは、処理されるすべてのMockXhrインスタンスに影響します。MockXhr.timeoutEnabled = false 。 MockXhrクラスのこの静的プロパティは、その各インスタンスに影響します。MockXhrインスタンスでtimeoutEnabled falseに設定します。これはそのインスタンスにのみ影響します。MockXhrライフサイクル フックの使用これは、 MockXhrServerを使用しない別の使用パターンです。代わりに、 MockXhrライフサイクル フックを直接使用します。これにはより多くのコードが必要ですが、 MockXhrリクエストをより詳細に制御できます。
モック サーバーを拡張するだけの場合は、 MockXhrライフサイクル フックをMockXhrServerと一緒に使用することもできることに注意してください。
例:
import { newMockXhr } from 'mock-xmlhttprequest' ;
import { functionToTest } from '../src/SomethingToTest' ;
// Adapt based on your testing framework. This example uses Mocha and Chai's syntax.
it ( 'should produce a success response' , async ( ) => {
// Get a "local" MockXhr subclass
const MockXhr = newMockXhr ( ) ;
// Mock JSON response
MockXhr . onSend = ( request ) => {
const responseHeaders = { 'Content-Type' : 'application/json' } ;
const response = '{ "message": "Success!" }' ;
request . respond ( 200 , responseHeaders , response ) ;
} ;
try {
// Install in the global context so "new XMLHttpRequest()" creates MockXhr instances
global . XMLHttpRequest = MockXhr ;
// Do something that send()s an XMLHttpRequest to '/my/url' and returns a Promise
// that resolves to the parsed JSON response
const result = await functionToTest ( ) ;
assert . equal ( result . message , 'Success!' ) ;
} finally {
// Restore the original XMLHttpRequest
delete global . XMLHttpRequest ;
}
} ) ; MockXhrServerクラスこのクラスは、URL とメソッドに基づいてMockXhrリクエストに応答するモック サーバーです。
MockXhrServerセットアップMockXhrServer(routes)引数:
routes : サーバーのルートの初期セットを含むオブジェクト。 (オプション)ほとんどの場合、このコンストラクターを直接使用する代わりにnewServer使用する必要があります。
routesオブジェクトのキーは HTTP メソッドです。値は、 [url_matcher, request_handler] 2 つの要素を含む配列です。
「リクエスト URL マッチャー」および「リクエスト ハンドラー」も参照してください。
例:
const handlerFn = ( request ) => { request . respond ( ) ; } ;
newServer ( {
get : [ '/get' , { status : 200 } ] ,
'my-method' : [ '/my-method' , { status : 201 } ] ,
post : [ '/post' , [ handlerFn , { status : 404 } ] ] ,
} ) ; install(context = globalThis)引数:
context : 値を指定すると、 installメソッドはグローバル コンテキストではなく、このコンテキストでXMLHttpRequestプロパティを設定します。 (オプション)サーバーのMockXhrモックをグローバル コンテキストにインストールして、 XMLHttpRequestクラスを置き換えます。 Remove()で元に戻します。
remove()install() によって加えられた変更を元に戻します。テスト後にこれを呼び出します。
progressRate progressRate 0 より大きいnumberに設定すると、サーバーはリクエスト (アップロード) および応答 (ダウンロード) の進行状況イベントを自動的に生成します。各進行状況イベントは、 progressRateバイトずつ増加します。
progressRateタイプobjectのリクエスト ハンドラーにのみ適用されます。
disableTimeout()とenableTimeout()これらのメソッドは、 MockXhrのtimeout属性の効果を無効または有効にします。 「 timeout属性とリクエストのタイムアウト」を参照してください。
ルートは、サーバーがMockXhrリクエストにどのように応答するかを構成します。それらの 3 つの部分については以下で説明します。
ルートの概念は、Express フレームワークに大まかに基づいています。
有効な HTTP リクエスト メソッドを含む任意のstringが許可されます。有効なメソッドには、 GET 、 POST 、 PUT 、 DELETEなどの標準メソッドと、その他のメソッド名が含まれます。標準のメソッド名では大文字と小文字が区別されません。
リクエスト URL マッチャーは次のタイプのいずれかになります。
string (例: '/my-url' )。RegExp 。trueを返すFunction 。関数は引数として URL を受け取ります。 リクエスト ハンドラーは次のいずれかのタイプになります。
応答プロパティを持つobject 。デフォルト値は次のとおりです。
{ status: 200, headers: {}, body: null, statusText: 'OK' }
模擬応答メソッドを直接呼び出すFunction 。この関数は、 MockXhrRequestインスタンスを引数として受け取ります。
値'error'または'timeout'を含むstring 。これにより、それぞれエラーまたはタイムアウトが発生します。
上記の他のリクエスト ハンドラー タイプの配列。最初のリクエストは最初のハンドラーを取得し、2 番目のリクエストは 2 番目のハンドラーを取得します。配列内にそれ以上のハンドラーが存在しない場合、最後のハンドラーが再利用されます。
object要求ハンドラーの場合、サーバーは応答本文の長さを含むContent-Length応答ヘッダーを自動的に追加します。
これらのハンドラーはすべて同等です。
const handlerObj = { } ;
const handlerFn = ( request ) => { request . respond ( 200 , { 'Content-Length' : '0' } ) ; } ;
const handlerArray = [ { } ] ; get(urlMatcher, handler)引数:
urlMatcher : URL マッチャーをリクエストします。handler : リクエストハンドラー。 GET HTTP メソッドのルートを追加します。
post(urlMatcher, handler)引数:
urlMatcher : URL マッチャーをリクエストします。handler : リクエストハンドラー。 POST HTTP メソッドのルートを追加します。
put(urlMatcher, handler)引数:
urlMatcher : URL マッチャーをリクエストします。handler : リクエストハンドラー。 PUT HTTP メソッドのルートを追加します。
delete(urlMatcher, handler)引数:
urlMatcher : URL マッチャーをリクエストします。handler : リクエストハンドラー。 DELETE HTTP メソッドのルートを追加します。
addHandler(method, urlMatcher, handler)引数:
method : stringとしての HTTP メソッド。urlMatcher : URL マッチャーをリクエストします。handler : リクエストハンドラー。 method HTTP メソッドのルートを追加します。
setDefaultHandler(handler)引数:
handler : リクエストハンドラー。どのルートにも一致しないリクエストに対するデフォルトのリクエスト ハンドラーを設定します。
setDefault404()404 応答を返すデフォルトのリクエスト ハンドラーを設定します。
xhrFactory新しいMockXhrインスタンスを返す関数。
MockXhrサーバーがフックするMockXhrクラス。 xhrFactoryこのクラスのインスタンスを作成します。
getRequestLog()これまでにサーバーが受信したすべてのリクエストの配列を返します。各呼び出しは新しい配列を返します。各配列要素は、次のプロパティを持つオブジェクトです。
method : HTTP メソッドstring 。url : URL string 。body : リクエストボディheaders : オブジェクトとしてのリクエストヘッダー。ヘッダー名は小文字です。MockXhrクラスこのクラスはXMLHttpRequestのモックです。このセクションでは、仕様に記載されていないメソッドとプロパティについて説明します。
MockXhr.timeoutEnabledこの静的boolean値プロパティは、クラスのすべてのインスタンスからのリクエストの自動タイムアウトを制御します。
timeoutEnabledこのboolean値プロパティは、このMockXhrインスタンスからの自動タイムアウトを制御します。
getResponseHeadersHash()すべての応答ヘッダーをオブジェクトとして返します。ヘッダー名は小文字です。
MockXhrライフサイクル フックMockXhrライフサイクル フックのコールバック メソッドは、次の場所で定義できます。
MockXhrクラスの静的プロパティ。フックは、 MockXhrとそのサブクラスのすべてのインスタンスに適用されます。MockXhrServer.MockXhrまたはnewMockXhr()によって返されるMockXhrサブクラスの静的プロパティ。フックはそのクラスのすべてのインスタンスに適用されます。MockXhrのインスタンスのプロパティ。フックはそのインスタンスにのみ適用されます。ライフサイクル イベントに複数のフックを定義した場合、それらは上記の順序で呼び出されます。
通常は、テスト ケースを分離しやすくする 3 番目のオプションを選択する必要があります。
onCreateこれらの引数を受け取るコールバック メソッド:
xhr : 新しいMockXhrインスタンス。このライフサイクル フックを使用して、 MockXhrのインスタンスを構築時にインターセプトします。
MockXhrのインスタンスが作成されるとき、そのコンストラクターの最後で呼び出されます。したがって、このライフサイクル フックは静的プロパティとしてのみ使用できます。
import { MockXhr , newMockXhr } from 'mock-xmlhttprequest' ;
// Called for all instances of MockXhr and all its subclasses
MockXhr . onCreate = ( xhr ) => { /*...*/ } ;
// Called for all instances of this MockXhr subclass
const MockXhrSubclass = newMockXhr ( ) ;
MockXhrSubclass . onCreate = ( xhr ) => { /*...*/ } ; onSendこれらの引数を受け取るコールバック メソッド:
request : リクエストのMockXhrRequest 。xhr : MockXhrインスタンス。このライフサイクル フックを使用して、模擬応答メソッドでリクエストに応答します。
send()を呼び出すたびに非同期的に呼び出されます。 send()を呼び出すたびに、 MockXhrRequestの個別のインスタンスを使用してonSendへの呼び出しが生成されます。
import { MockXhr , newMockXhr } from 'mock-xmlhttprequest' ;
// Called for all instances of MockXhr and all its subclasses
MockXhr . onSend = ( request ) => { /*...*/ } ;
// Called for all instances of this MockXhr subclass
const MockXhrSubclass = newMockXhr ( ) ;
MockXhrSubclass . onSend = ( request ) => { /*...*/ } ;
// Called for this instance only
const xhr = new MockXhrSubclass ( ) ;
xhr . onSend = ( request ) => { /*...*/ } ;MockXhrRequestクラスsend()を呼び出すたびに、 XMLHttpRequestに関する情報を含むMockXhrRequestが作成され、プログラムで応答するメソッドが提供されます。
requestHeadersリクエストのヘッダーのコピーを含むHeadersContainer 。
methodリクエストの HTTP メソッドを含む文字string 。
urlリクエストの URL を含むstring 。
bodyリクエストの本文。
withCredentialsリクエストのwithCredentials値を含むboolean 。
getRequestBodySize()リクエスト本文のバイトnumber 。
注: body multipart/form-dataでエンコードされたFormDataである場合、これは完全に正確ではありません。ヘッダー、エンコーディング、およびモック化されていないXMLHttpRequestの実際のbodyサイズに寄与するその他の要素は考慮されません。このメソッドを使用すると、リクエストの実際のbodyサイズの下限値を取得できます。これは、アップロードの進行状況イベントをシミュレートするのに役立ちます。
これらのメソッドは、 MockXhrリクエストに応答するためのプログラム インターフェイスを提供します。
応答メソッドの呼び出しが無効な場合、 "Mock usage error detected"を含むメッセージを含むErrorスローされます。
uploadProgress(transmitted)引数:
transmitted : 送信されたバイトnumber 。アップロードの進行状況のリクエストを発行します。
これは、リクエストのbodyがnullでなく、アップロードが完了していない場合にのみ呼び出すことができます。
このメソッドを呼び出した後は、他の模擬応答メソッドを使用できます。
respond(status = 200, headers = {}, body = null, statusText = 'OK')引数:
status : 応答 HTTP ステータスnumber 。 (オプション)headers : 応答ヘッダーを含むobject 。 (オプション)body : レスポンスボディ。 (オプション)statusText : string応答 HTTP ステータス テキスト。 (オプション)応答ヘッダーと本文の両方を設定する完全な応答メソッド。リクエストのreadyStateをDONEに変更します。
適切なイベント ( readystatechange 、 progress 、 loadなど) を発生させます。
これは、 setResponseHeaders()の後にsetResponseBody()が続く短縮形です。
このメソッドを呼び出した後は、他の疑似応答メソッドを使用できません。この制限は、 open()再度呼び出すと解除されます。
setResponseHeaders(status = 200, headers = {}, statusText = 'OK')引数:
status : 応答 HTTP ステータスnumber 。 (オプション)headers : 応答ヘッダーを含むobject 。 (オプション)statusText : string応答 HTTP ステータス テキスト。 (オプション)応答ヘッダーを設定します。リクエストのreadyStateをHEADERS_RECEIVEDに変更します。
適切なイベント ( readystatechange 、 progress 、 loadなど) を発生させます。
このメソッドを呼び出した後、次の模擬応答メソッドを使用できます。
downloadProgress()setResponseBody()setNetworkError()setRequestTimeout() 。 downloadProgress(transmitted, length)引数:
transmitted : 送信されたバイトnumber 。length : 応答内のバイトnumber 。応答進行状況イベントを発生させます。 HEADERS_RECEIVEDの場合、リクエストのreadyStateをLOADINGに変更します。
このメソッドの前にsetResponseHeaders()を呼び出す必要があります。
setResponseBody(body = null)引数:
body : レスポンスボディ。 (オプション)レスポンスボディを設定します。リクエストのreadyState DONEに変更します。
適切なイベント ( readystatechange 、 progress 、 loadなど) を発生させます。
まだ呼び出されていなければsetResponseHeaders()を呼び出します。応答ヘッダーには、応答本文の長さと同じ値を持つContent-Lengthのみが含まれます。
このメソッドを呼び出した後は、他の疑似応答メソッドを使用できません。この制限は、 open()再度呼び出すと解除されます。
setNetworkError()ネットワークエラーをシミュレートします。リクエストのreadyStateをDONEに変更します。
errorイベントを含む適切なイベントを発生させます。
このメソッドを呼び出した後は、他の疑似応答メソッドを使用できません。この制限は、 open()再度呼び出すと解除されます。
setRequestTimeout()リクエストのタイムアウトをシミュレートします。リクエストのreadyState DONEに変更します。
timeoutイベントを含む適切なイベントを発生させます。
request属性が 0 の場合はタイムアウトが発生しないため、エラーがスローされます。
このメソッドを呼び出した後は、他の疑似応答メソッドを使用できません。この制限は、 open()再度呼び出すと解除されます。
newMockXhr()新しいMockXhrサブクラスを返します。
各テスト ケースでMockXhrの異なるサブクラスを使用すると、テスト ケースが自己完結していることを確認するのが簡単になります。たとえば、サブクラスにtimeoutEnabled静的プロパティを設定すると、そのサブクラスにのみ影響し、他のテスト ケースで作成された他のサブクラスには影響しません。サブクラスは再利用されないため、サブクラスに加えられた変更を元に戻すクリーンアップ コードは必要ありません。
newServer(routes)引数:
routes : サーバーのルートの初期セットを含むオブジェクト。 (オプション)独自の一意のMockXhrサブクラスを持つ新しいMockXhrServerを返します。 newMockXhr()参照してください。
オプションのroutes引数を使用してルートをMockXhrServerに追加します。詳細についてはコンストラクターを参照してください。
XMLHttpRequest機能XMLHTTPRequest 仕様バージョン「2022 年 8 月 15 日」に基づいています。
open() 、 setRequestHeader() 、 send()およびabort() 。statusText 、ヘッダーおよび本文。timeout属性 (無効化可能)。MockXhr.setNetworkError()を参照)。MockXhr.setRequestTimeout()を参照)。overrideMimeType()必要に応じてスローしますが、それ以外の効果はありません。responseType : '' 、 'text'および'json'は完全にサポートされています。 responseType値は、 setResponseBody()に渡される応答本文には影響しません。responseXml : 応答本文はドキュメント応答に変換されません。ドキュメントの応答を取得するには、それをsetResponseBody()の応答本文として直接渡します。responseUrl : リダイレクト後の最終リクエスト URL は自動的に設定されません。これはリクエスト ハンドラーでエミュレートできます。async open()でfalseに設定される)。open()でリクエスト URL を解析し、失敗した場合はSyntaxErrorをスローします。 寄稿者は大歓迎です!詳細については、このガイドを参照してください。
マサチューセッツ工科大学