このライブラリは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
をスローします。 寄稿者は大歓迎です!詳細については、このガイドを参照してください。
マサチューセッツ工科大学