Pustaka ini adalah tiruan XMLHttpRequest yang menyediakan antarmuka sederhana untuk mensimulasikan interaksi dengan XMLHttpRequest . Ini adalah pengganti XMLHttpRequest untuk pengujian Anda.
Pustaka ini mengimplementasikan antarmuka XMLHttpRequest dan menangani permintaan dan kejadian seperti yang ditentukan dalam spesifikasi XMLHTTPRequest tanpa menggunakan permintaan jaringan nyata. Anda dapat menanggapi permintaan tiruan dengan tiga cara:
Anda dapat menyimulasikan respons, kemajuan unggahan, kesalahan, dan interaksi lainnya dengan metode respons tiruan. Ini secara otomatis menangani pemrosesan tingkat rendah seperti memancarkan peristiwa dan mengubah properti readystate XMLHttpRequest .
MockXhr secara terprogramtimeout dan batas waktu permintaanMockXhrMockXhrServerMockXhrServerMockXhrMockXhrMockXhrRequestnewMockXhr()newServer()XMLHttpRequestmelalui npm (manajer paket simpul)
$ 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 ( ) ;
}
} ) ; Kelas tiruan XMLHttpRequest adalah MockXhr . Ini memperlihatkan antarmuka yang sama dengan XMLHttpRequest dan merupakan pengganti drop-in untuk menguji kode yang menggunakan XMLHttpRequest .
Ada dua opsi untuk mengontrol perilaku instance MockXhr :
XMLHttpRequest . Gunakan ini jika Anda memerlukan kontrol lebih besar atas permintaan tanpa fitur yang disediakan oleh server tiruan. Kelas MockXhrServer mengimplementasikan server tiruan. Anda membuat MockXhrServer dengan newServer . MockXhrServer secara otomatis merespons permintaan MockXhr dan mempermudah tes penulisan.
Struktur dasar pengujian yang menggunakan MockXhrServer adalah:
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 ( ) ;
} Ada dua pendekatan untuk membuat kode Anda menggunakan kelas MockXhr sebagai pengganti XMLHttpRequest . Hal ini memungkinkan MockXhrServer untuk menanggapi permintaan:
install() untuk mengganti kelas XMLHttpRequest secara global dengan kelas MockXhr server. Di akhir kasus uji, panggil remove() untuk mengembalikan keadaan semula.XMLHttpRequest , gunakan kelas MockXhr secara langsung dengan salah satu properti MockXhrServer berikut:xhrFactory adalah fungsi yang membuat instance MockXhr .MockXhr adalah kelas instance yang dibuat oleh xhrFactory . Kode ini menunjukkan penggunaan 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 ;
} Rute menentukan bagaimana MockXhrServer merespons permintaan MockXhr . Ini memiliki tiga bagian:
Saat Anda mengirim permintaan MockXhr , MockXhrServer menemukan rute pertama yang cocok dengan metode dan URL permintaan. Kemudian merespons dengan penangan permintaan rute. Anda juga dapat menyetel penangan permintaan default. Penangan permintaan didefinisikan secara deklaratif atau terprogram.
Secara default, jika atribut timeout permintaan diatur ke nilai bukan nol dan MockXhrServer tidak merespons permintaan tersebut, waktu habis pada akhirnya.
Ada dua cara untuk menambahkan rute ke MockXhrServer :
routes dari newServer .MockXhrServer yang menambahkan rute. MockXhrServer mencatat semua permintaan MockXhr yang diterimanya dalam log permintaan. Gunakan ini untuk memvalidasi permintaan XMLHttpRequest yang dikirimkan kode Anda.
MockXhrServer dapat menghasilkan peristiwa kemajuan permintaan (unggah) dan respons (unduh) secara otomatis. Ini dinonaktifkan secara default. Gunakan bidang progressRate untuk mengaktifkan ini.
Anda juga dapat menghasilkan peristiwa kemajuan jika Anda merespons permintaan MockXhr secara terprogram dengan penangan permintaan bertipe Function .
Respons terhadap permintaan MockXhr tidak sinkron. Ini mereproduksi cara kerja permintaan XMLHttpRequest yang sebenarnya. Oleh karena itu, kemungkinan besar Anda perlu menggunakan dukungan pengujian asinkron pada kerangka pengujian Anda. Misalnya, dokumentasi yang relevan untuk kerangka pengujian Mocha ada di sini.
Kait siklus hidup onSend diperlukan untuk merespons permintaan MockXhr . Server tiruan menangani ini secara otomatis. Opsi lainnya adalah menggunakan kait siklus hidup MockXhr secara langsung. Dalam kedua kasus tersebut, hook siklus hidup onSend dijalankan setelah konteks eksekusi yang memanggil XMLHttpRequest.send() selesai atau dihapus. Secara internal perpustakaan ini menggunakan Promise yang segera diselesaikan untuk mendapatkan tumpukan panggilan kosong.
MockXhr secara terprogram Ada beberapa metode dan properti MockXhr untuk merespons permintaan. Metode ini memungkinkan interaksi berikut:
Lihat bagian Metode respons tiruan untuk detailnya.
timeout dan batas waktu permintaan Secara default, jika Anda menyetel atribut timeout XMLHttpRequest dalam kode Anda, permintaan MockXhr akan habis secara otomatis setelah penundaan yang ditentukan. Ini memunculkan peristiwa timeout dan membatalkan permintaan seperti yang dijelaskan dalam spesifikasi.
Mengandalkan berlalunya waktu untuk menguji bagaimana kode Anda menangani waktu tunggu biasanya membuat pengujian menjadi rapuh dan sulit untuk di-debug. Anda malah dapat memicu waktu tunggu secara terprogram dengan setRequestTimeout() .
Nonaktifkan batas waktu permintaan otomatis dengan salah satu opsi berikut:
disableTimeout() pada MockXhrServer . Ini mempengaruhi semua instance MockXhr yang ditanganinya.MockXhr.timeoutEnabled = false . Properti statis pada kelas MockXhr ini memengaruhi setiap instance-nya.timeoutEnabled ke false pada instans MockXhr . Ini hanya mempengaruhi kejadian itu saja.MockXhr Ini adalah pola penggunaan alternatif yang tidak menggunakan MockXhrServer . Anda malah menggunakan kait siklus hidup MockXhr secara langsung. Ini memerlukan lebih banyak kode, tetapi Anda memiliki kontrol lebih besar atas permintaan MockXhr .
Perhatikan bahwa Anda juga dapat menggunakan kait siklus hidup MockXhr bersama dengan MockXhrServer jika Anda hanya perlu memperluas server tiruan.
Contoh:
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 Kelas ini adalah server tiruan yang merespons permintaan MockXhr berdasarkan URL dan metodenya.
MockXhrServer MockXhrServer(routes)Argumen:
routes : Objek dengan kumpulan rute awal server. (opsional) Dalam kebanyakan kasus, Anda harus menggunakan newServer alih-alih konstruktor ini secara langsung.
Kunci dari objek routes adalah metode HTTP. Nilainya adalah array dengan dua elemen: [url_matcher, request_handler] .
Lihat juga Minta pencocokan URL dan Penangan permintaan.
Contoh:
const handlerFn = ( request ) => { request . respond ( ) ; } ;
newServer ( {
get : [ '/get' , { status : 200 } ] ,
'my-method' : [ '/my-method' , { status : 201 } ] ,
post : [ '/post' , [ handlerFn , { status : 404 } ] ] ,
} ) ; install(context = globalThis)Argumen:
context : Jika Anda memberikan nilai, metode install akan menetapkan properti XMLHttpRequest dalam konteks ini, bukan konteks global. (opsional) Menginstal tiruan MockXhr server dalam konteks global untuk menggantikan kelas XMLHttpRequest . Kembalikan dengan hapus().
remove()Mengembalikan perubahan yang dibuat oleh install(). Sebut ini setelah tes Anda.
progressRate Jika Anda menyetel progressRate ke number yang lebih besar dari 0, server secara otomatis menghasilkan peristiwa kemajuan permintaan (unggahan) dan respons (unduh). Setiap peristiwa kemajuan bertambah berdasarkan byte progressRate .
progressRate hanya berlaku untuk penangan permintaan bertipe object .
disableTimeout() dan enableTimeout() Metode ini menonaktifkan atau mengaktifkan efek atribut timeout MockXhr . Lihat "Atribut timeout dan batas waktu permintaan".
Rute mengonfigurasi cara server merespons permintaan MockXhr . Ketiga bagiannya dijelaskan di bawah ini.
Konsep rute secara longgar didasarkan pada kerangka Express.
string apa pun dengan metode permintaan HTTP yang valid diperbolehkan. Metode yang valid mencakup metode standar seperti GET , POST , PUT dan DELETE , serta nama metode lainnya. Nama metode standar tidak peka huruf besar-kecil.
Pencocokan URL permintaan dapat berupa salah satu dari jenis berikut:
string (misalnya '/my-url' ) yang sama persis dengan URL permintaan.RegExp yang cocok dengan URL permintaan.Function yang mengembalikan true jika URL permintaan cocok. Fungsi tersebut menerima URL sebagai argumen. Penangan permintaan dapat berupa salah satu dari jenis berikut:
Sebuah object dengan properti respon. Nilai defaultnya adalah:
{ status: 200, headers: {}, body: null, statusText: 'OK' }
Function yang memanggil metode respons tiruan secara langsung. Fungsi tersebut menerima instance MockXhrRequest sebagai argumen.
string dengan nilai 'error' atau 'timeout' . Ini masing-masing memicu kesalahan atau batas waktu.
Array tipe penangan permintaan lainnya di atas. Permintaan pertama mendapat penangan pertama, permintaan kedua mendapat penangan kedua, dan seterusnya. Penangan terakhir digunakan kembali ketika tidak ada lagi penangan dalam array.
Untuk penangan permintaan object , server secara otomatis menambahkan header respons Content-Length dengan panjang isi respons.
Semua penangan ini setara:
const handlerObj = { } ;
const handlerFn = ( request ) => { request . respond ( 200 , { 'Content-Length' : '0' } ) ; } ;
const handlerArray = [ { } ] ; get(urlMatcher, handler)Argumen:
urlMatcher : Minta pencocokan URL.handler : Permintaan handler. Menambahkan rute untuk metode GET HTTP.
post(urlMatcher, handler)Argumen:
urlMatcher : Minta pencocokan URL.handler : Permintaan handler. Menambahkan rute untuk metode POST HTTP.
put(urlMatcher, handler)Argumen:
urlMatcher : Minta pencocokan URL.handler : Permintaan handler. Menambahkan rute untuk metode PUT HTTP.
delete(urlMatcher, handler)Argumen:
urlMatcher : Minta pencocokan URL.handler : Permintaan handler. Menambahkan rute untuk metode DELETE HTTP.
addHandler(method, urlMatcher, handler)Argumen:
method : Metode HTTP sebagai string .urlMatcher : Minta pencocokan URL.handler : Permintaan handler. Menambahkan rute untuk method metode HTTP.
setDefaultHandler(handler)Argumen:
handler : Permintaan handler.Menetapkan penangan permintaan default untuk permintaan yang tidak cocok dengan rute mana pun.
setDefault404()Menetapkan penangan permintaan default yang mengembalikan respons 404.
xhrFactory Fungsi yang mengembalikan instance MockXhr baru.
MockXhr Kelas MockXhr yang dihubungkan oleh server. xhrFactory membuat instance kelas ini.
getRequestLog()Mengembalikan array dari semua permintaan yang diterima oleh server sejauh ini. Setiap panggilan mengembalikan array baru. Setiap elemen array adalah objek dengan properti berikut:
method : string metode HTTP.url : string URL .body : badan permintaanheaders : meminta header sebagai objek. Nama header menggunakan huruf kecil.MockXhr Kelas ini adalah tiruan dari XMLHttpRequest . Bagian ini mendokumentasikan metode dan propertinya yang tidak ada dalam spesifikasi.
MockXhr.timeoutEnabled Properti boolean statis ini mengontrol batas waktu otomatis permintaan dari semua instance kelas.
timeoutEnabled Properti boolean ini mengontrol batas waktu otomatis dari instance MockXhr ini.
getResponseHeadersHash()Mengembalikan semua header respons sebagai objek. Nama header menggunakan huruf kecil.
MockXhr Anda dapat menentukan metode panggilan balik untuk kait siklus hidup MockXhr di lokasi berikut:
MockXhr . Hook berlaku untuk semua instance MockXhr dan subkelasnya.MockXhr dikembalikan oleh MockXhrServer.MockXhr atau newMockXhr() . Hook berlaku untuk semua instance dari kelas itu.MockXhr . Pengait hanya berlaku untuk instance tersebut.Jika Anda menentukan beberapa kait untuk peristiwa siklus hidup, kait tersebut akan dipanggil sesuai urutan di atas.
Biasanya Anda sebaiknya memilih opsi ketiga yang membuatnya lebih mudah untuk mengisolasi kasus pengujian Anda.
onCreateMetode panggilan balik yang menerima argumen berikut:
xhr : Contoh MockXhr baru. Gunakan kait siklus hidup ini untuk mencegat instance MockXhr saat dibuat.
Dipanggil ketika sebuah instance MockXhr dibuat, di akhir konstruktornya. Oleh karena itu, kait siklus hidup ini hanya tersedia sebagai properti statis.
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 ) => { /*...*/ } ; onSendMetode panggilan balik yang menerima argumen berikut:
request : MockXhrRequest untuk permintaan tersebut.xhr : Contoh MockXhr .Gunakan kait siklus hidup ini untuk merespons permintaan dengan metode respons tiruan.
Dipanggil secara asinkron setelah setiap panggilan ke send() . Setiap panggilan ke send() menghasilkan panggilan ke onSend dengan instance MockXhrRequest yang terpisah.
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 Setiap panggilan ke send() membuat MockXhrRequest yang berisi informasi tentang XMLHttpRequest dan menyediakan metode untuk merespons secara terprogram.
requestHeaders HeadersContainer yang berisi salinan header permintaan.
method Sebuah string dengan metode HTTP permintaan.
url Sebuah string dengan URL permintaan.
bodyIsi permintaan.
withCredentials boolean dengan nilai withCredentials permintaan.
getRequestBodySize() number byte di badan permintaan.
Catatan: ini tidak sepenuhnya akurat jika body FormData dikodekan dengan multipart/form-data . Header, pengkodean, dan faktor lain yang berkontribusi pada ukuran body sebenarnya XMLHttpRequest yang tidak diejek tidak dipertimbangkan. Anda dapat menggunakan metode ini untuk mendapatkan nilai dasar untuk ukuran body sebenarnya dari permintaan. Ini berguna untuk menyimulasikan peristiwa kemajuan unggahan.
Metode ini menyediakan antarmuka terprogram untuk merespons permintaan MockXhr .
Jika panggilan ke metode respons tidak valid, maka akan muncul Error dengan pesan yang berisi "Mock usage error detected" .
uploadProgress(transmitted)Argumen:
transmitted : number byte yang ditransmisikan.Meluncurkan kemajuan unggahan permintaan.
Anda hanya dapat memanggil ini jika body permintaan bukan null dan pengunggahan belum selesai.
Setelah Anda memanggil metode ini, Anda dapat menggunakan metode respons tiruan lainnya.
respond(status = 200, headers = {}, body = null, statusText = 'OK')Argumen:
status : number status HTTP respons. (opsional)headers : object dengan header respons. (opsional)body : Tubuh respons. (opsional)statusText : respons string teks status HTTP. (opsional) Metode respons lengkap yang menetapkan header dan isi respons. Mengubah readyState permintaan menjadi DONE .
Mengaktifkan peristiwa yang sesuai seperti readystatechange , progress , dan load .
Ini adalah singkatan dari setResponseHeaders() diikuti oleh setResponseBody() .
Setelah Anda memanggil metode ini, Anda tidak dapat menggunakan metode respons tiruan lainnya. Pembatasan ini dicabut jika Anda memanggil open() lagi.
setResponseHeaders(status = 200, headers = {}, statusText = 'OK')Argumen:
status : number status HTTP respons. (opsional)headers : object dengan header respons. (opsional)statusText : respons string teks status HTTP. (opsional) Mengatur header respons. Mengubah readyState permintaan menjadi HEADERS_RECEIVED .
Mengaktifkan peristiwa yang sesuai seperti readystatechange , progress , dan load .
Setelah memanggil metode ini, Anda dapat menggunakan metode respons tiruan berikut:
downloadProgress()setResponseBody()setNetworkError()setRequestTimeout() . downloadProgress(transmitted, length)Argumen:
transmitted : number byte yang ditransmisikan.length : number byte dalam respons. Meluncurkan peristiwa kemajuan respons. Mengubah readyState permintaan menjadi LOADING jika HEADERS_RECEIVED .
Anda harus memanggil setResponseHeaders() sebelum metode ini.
setResponseBody(body = null)Argumen:
body : Tubuh respons. (opsional) Mengatur isi respons. Mengubah readyState permintaan menjadi DONE .
Mengaktifkan peristiwa yang sesuai seperti readystatechange , progress , dan load .
Memanggil setResponseHeaders() jika belum dipanggil. Header respons kemudian hanya berisi Content-Length dengan nilai yang sama dengan panjang isi respons.
Setelah Anda memanggil metode ini, Anda tidak dapat menggunakan metode respons tiruan lainnya. Pembatasan ini dicabut jika Anda memanggil open() lagi.
setNetworkError() Mensimulasikan kesalahan jaringan. Mengubah readyState permintaan menjadi DONE .
Mengaktifkan peristiwa yang sesuai termasuk peristiwa error .
Setelah Anda memanggil metode ini, Anda tidak dapat menggunakan metode respons tiruan lainnya. Pembatasan ini dicabut jika Anda memanggil open() lagi.
setRequestTimeout() Mensimulasikan batas waktu permintaan. Mengubah readyState permintaan menjadi DONE .
Mengaktifkan peristiwa yang sesuai termasuk peristiwa timeout .
Memunculkan kesalahan jika atribut request sama dengan 0 karena batas waktu tidak terjadi dalam kasus tersebut.
Setelah Anda memanggil metode ini, Anda tidak dapat menggunakan metode respons tiruan lainnya. Pembatasan ini dicabut jika Anda memanggil open() lagi.
newMockXhr() Mengembalikan subkelas MockXhr baru.
Jika Anda menggunakan subkelas MockXhr yang berbeda di setiap kasus pengujian, akan lebih mudah untuk memastikan subkelas tersebut mandiri. Misalnya, jika Anda menyetel properti statis timeoutEnabled pada subkelas, itu hanya memengaruhi subkelas tersebut dan bukan subkelas lain yang dibuat dalam kasus pengujian lainnya. Karena subkelas tidak digunakan kembali, kode pembersihan yang mengembalikan perubahan yang dibuat pada subkelas tidak diperlukan.
newServer(routes)Argumen:
routes : Objek dengan kumpulan rute awal server. (opsional) Mengembalikan MockXhrServer baru dengan subkelas MockXhr uniknya sendiri. Lihat newMockXhr() .
Tambahkan rute ke MockXhrServer dengan argumen routes opsional. Lihat konstruktor untuk detailnya.
XMLHttpRequestBerdasarkan spesifikasi XMLHTTPRequest versi '15 Agustus 2022'.
open() , setRequestHeader() , send() dan abort() .statusText , header dan isi.timeout (dapat dinonaktifkan).MockXhr.setNetworkError() ).MockXhr.setRequestTimeout() ).overrideMimeType() muncul saat diperlukan, tetapi tidak memiliki efek lain.responseType : '' , 'text' dan 'json' didukung sepenuhnya. Nilai responseType tidak berpengaruh pada isi respons yang diteruskan ke setResponseBody() .responseXml : isi respons tidak dikonversi menjadi respons dokumen. Untuk mendapatkan respons dokumen, teruskan langsung sebagai isi respons di setResponseBody() .responseUrl : URL permintaan terakhir setelah pengalihan tidak disetel secara otomatis. Ini dapat ditiru dalam penangan permintaan.async disetel ke false di open() ).open() dan melemparkan SyntaxError jika gagal. Kontributor dipersilakan! Lihat panduan ini untuk info lebih lanjut.
MIT