Saya terus mendapatkan "localStorage tidak didefinisikan" dalam tes Jest yang masuk akal tapi apa pilihan saya? Memukul dinding bata.
144
Solusi hebat dari @chiedo
Namun, kami menggunakan sintaks ES2015 dan saya merasa sedikit lebih bersih untuk menulisnya dengan cara ini.
class LocalStorageMock {
constructor() {
this.store = {};
}
clear() {
this.store = {};
}
getItem(key) {
return this.store[key] || null;
}
setItem(key, value) {
this.store[key] = value.toString();
}
removeItem(key) {
delete this.store[key];
}
};
global.localStorage = new LocalStorageMock;
value + ''
di setter untuk menangani nilai nol dan tidak terdefinisi dengan benar|| null
sebabnya pengujian saya gagal, karena dalam pengujian saya saya gunakannot.toBeDefined()
. Solusi @Chiedo membuatnya bekerja lagiCari tahu dengan bantuan ini: https://groups.google.com/forum/#!topic/jestjs/9EPhuNWVYTg
Siapkan file dengan konten berikut:
Kemudian Anda menambahkan baris berikut ke package.json Anda di bawah konfigurasi Jest Anda
"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",
sumber
"setupFiles": [...]
berfungsi juga. Dengan opsi array, memungkinkan memisahkan tiruan menjadi file yang terpisah. Misalnya:"setupFiles": ["<rootDir>/__mocks__/localStorageMock.js"]
getItem
sedikit berbeda dengan apa yang akan dikembalikan oleh browser jika tidak ada data yang ditetapkan terhadap kunci tertentu. menelepongetItem("foo")
ketika tidak diatur misalnya akan kembalinull
di browser, tetapiundefined
dengan tiruan ini - ini menyebabkan salah satu pengujian saya gagal. Solusi sederhana bagi saya adalah kembalistore[key] || null
kegetItem
fungsilocalStorage['test'] = '123'; localStorage.getItem('test')
Jika menggunakan aplikasi create-react, ada solusi yang lebih sederhana dan langsung dijelaskan dalam dokumentasi .
Buat
src/setupTests.js
dan letakkan ini di dalamnya:Kontribusi Tom Mertz dalam komentar di bawah:
Anda kemudian dapat menguji bahwa fungsi localStorageMock Anda digunakan dengan melakukan sesuatu seperti
di dalam tes Anda jika Anda ingin memastikan itu dipanggil. Lihat https://facebook.github.io/jest/docs/en/mock-functions.html
sumber
localStorage
Anda gunakan dalam kode Anda. (jika Anda menggunakancreate-react-app
dan semua skrip otomatis yang disediakannya secara alami)expect(localStorage.getItem).toBeCalledWith('token')
atauexpect(localStorage.getItem.mock.calls.length).toBe(1)
di dalam tes Anda jika Anda ingin memastikan itu dipanggil. Lihat facebook.github.io/jest/docs/en/mock-functions.htmllocalStorage
? Tidakkah Anda ingin mengatur ulang mata-mata setelah setiap tes untuk mencegah "limpahan" ke dalam tes lain?Saat ini (Oktober '19) penyimpanan lokal tidak dapat diejek atau dimata-matai dengan bercanda seperti yang biasa Anda lakukan, dan sebagaimana diuraikan dalam dokumen app-react-app. Ini karena perubahan yang dilakukan di jsdom. Anda bisa membacanya di gurauan dan kegelisahan pelacak masalah .
Sebagai solusinya, Anda dapat memata-matai prototipe sebagai gantinya:
sumber
jest.spyOn(window.localStorage.__proto__, 'setItem');
atau Anda hanya mengambil paket tiruan seperti ini:
https://www.npmjs.com/package/jest-localstorage-mock
tidak hanya menangani fungsi penyimpanan tetapi juga memungkinkan Anda menguji apakah toko itu benar-benar dipanggil.
sumber
Alternatif yang lebih baik yang menangani
undefined
nilai (tidak adatoString()
) dan kembalinull
jika nilai tidak ada. Menguji ini denganreact
v15,redux
danredux-auth-wrapper
sumber
removeItem
: developer.mozilla.org/en-US/docs/Web/API/Storage/removeItemJika Anda mencari tiruan dan bukan sebuah rintisan, berikut adalah solusi yang saya gunakan:
Saya mengekspor item penyimpanan agar mudah diinisialisasi. Yaitu saya dapat dengan mudah mengaturnya ke objek
Di versi Jest + JSDom yang lebih baru tidak mungkin untuk mengatur ini, tetapi penyimpanan lokal sudah tersedia dan Anda dapat memata-matai itu seperti ini:
sumber
Saya menemukan solusi ini dari github
Anda dapat memasukkan kode ini di setupTests Anda dan itu akan berfungsi dengan baik.
Saya mengujinya dalam proyek dengan typesctipt.
sumber
Sayangnya, solusi yang saya temukan di sini tidak berhasil untuk saya.
Jadi saya melihat masalah Jest GitHub dan menemukan utas ini
Solusi yang paling banyak dipilih adalah:
sumber
window
atauStorage
mendefinisikan. Mungkin itu versi lama Jest yang saya gunakan.Sebagai @ ck4 disarankan dokumentasi memiliki penjelasan yang jelas untuk digunakan
localStorage
dalam bercanda. Namun fungsi tiruan gagal menjalankan salah satulocalStorage
metode.Di bawah ini adalah contoh terperinci dari komponen reaksi saya yang memanfaatkan metode abstrak untuk menulis dan membaca data,
Kesalahan:
Fix:
Tambah bawah fungsi mock untuk bercanda (path:
.jest/mocks/setUpStore.js
)Cuplikan direferensikan dari sini
sumber
Riffed off beberapa jawaban lain di sini untuk menyelesaikannya untuk proyek dengan naskah. Saya membuat LocalStorageMock seperti ini:
Kemudian saya membuat kelas LocalStorageWrapper yang saya gunakan untuk semua akses ke penyimpanan lokal di aplikasi alih-alih secara langsung mengakses variabel penyimpanan lokal global. Memudahkan untuk mengatur tiruan di bungkusnya untuk tes.
sumber
Buat tiruan dan tambahkan ke
global
objektsumber
Anda dapat menggunakan pendekatan ini, untuk menghindari cemoohan.
sumber
Anda perlu mengejek penyimpanan lokal dengan cuplikan ini
// localStorage.js
Dan dalam konfigurasi bercanda:
Jangan ragu untuk bertanya apa pun.
sumber
Solusi berikut ini kompatibel untuk menguji dengan ketat naskah, ESLint, TSLint, dan lebih cantik config:
{ "proseWrap": "always", "semi": false, "singleQuote": true, "trailingComma": "es5" }
:HT / https://stackoverflow.com/a/51583401/101290 untuk cara memperbarui global.localStorage
sumber
Untuk melakukan hal yang sama dalam naskah, lakukan hal berikut:
Siapkan file dengan konten berikut:
Kemudian Anda menambahkan baris berikut ke package.json Anda di bawah konfigurasi Jest Anda
"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",
Atau Anda mengimpor file ini dalam test case di mana Anda ingin mengejek penyimpanan lokal.
sumber
Ini berhasil untuk saya,
sumber