Yanıtlar:
@Chiedo'dan harika çözüm
Ancak, ES2015 sözdizimini kullanıyoruz ve bu şekilde yazmanın biraz daha temiz olduğunu hissettim.
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;
|| null
yüzden testimin başarısız olduğunu düşünüyorum çünkü testimde kullanıyordum not.toBeDefined()
. @Chiedo çözümü tekrar çalışıyor
Şunun yardımıyla çözdüm: https://groups.google.com/forum/#!topic/jestjs/9EPhuNWVYTg
Aşağıdaki içeriklere sahip bir dosya kurun:
var localStorageMock = (function() {
var store = {};
return {
getItem: function(key) {
return store[key];
},
setItem: function(key, value) {
store[key] = value.toString();
},
clear: function() {
store = {};
},
removeItem: function(key) {
delete store[key];
}
};
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });
Ardından, Jest yapılandırmalarınızın altındaki package.json dosyasına aşağıdaki satırı eklersiniz
"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",
"setupFiles": [...]
çalışır. Dizi seçeneği ile alayları ayrı dosyalara ayırmaya izin verir. Örn:"setupFiles": ["<rootDir>/__mocks__/localStorageMock.js"]
getItem
Belirli bir anahtara karşı herhangi bir veri ayarlanmadığı takdirde, dönüş değeri tarayıcı tarafından döndürülecek değerden biraz farklıdır. getItem("foo")
ayarlanmadığında arama , örneğin null
bir tarayıcıda dönecektir , ancak undefined
bu sahte tarafından - bu, testlerimden birinin başarısız olmasına neden oluyordu. Benim için basit bir çözüm dönmek oldu store[key] || null
yılında getItem
fonksiyonu
localStorage['test'] = '123'; localStorage.getItem('test')
Create-tepki uygulaması kullanıyorsanız, dokümantasyonda açıklanan daha basit ve anlaşılır bir çözüm vardır .
src/setupTests.js
Bunu oluşturun ve içine koyun:
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
clear: jest.fn()
};
global.localStorage = localStorageMock;
Tom Mertz aşağıdaki yorumda katkıda bulundu:
Daha sonra localStorageMock işlevlerinin kullanıldığını test edebilirsiniz.
expect(localStorage.getItem).toBeCalledWith('token')
// or
expect(localStorage.getItem.mock.calls.length).toBe(1)
denendiğinden emin olmak istiyorsanız testlerinizin içinde. Check out https://facebook.github.io/jest/docs/en/mock-functions.html
localStorage
kodunuzda kullandığınız otomatik olarak alay eder . ( create-react-app
doğal olarak sağladığı tüm otomatik komut dosyalarını kullanırsanız )
expect(localStorage.getItem).toBeCalledWith('token')
veya expect(localStorage.getItem.mock.calls.length).toBe(1)
içine bir şey yaparak localStorageMock işlevlerinin kullanıldığını test edebilirsiniz. Check out facebook.github.io/jest/docs/en/mock-functions.html
localStorage
? Diğer testlere "yayılmasını" önlemek için her testten sonra casusları sıfırlamak istemez misiniz?
Şu anda (Ekim '19) localStorage, genellikle yaptığınız gibi ve oluştur-tepki-uygulama belgelerinde belirtildiği gibi jest tarafından alay edilemez veya casusluk edilemez. Bunun nedeni jsdom'da yapılan değişikliklerdir. Sen bu konuda okuyabilir jest ve jsdom sorunu izleyiciler.
Geçici bir çözüm olarak, prototip üzerinde casusluk yapabilirsiniz:
// does not work:
jest.spyOn(localStorage, "setItem");
localStorage.setItem = jest.fn();
// works:
jest.spyOn(window.localStorage.__proto__, 'setItem');
window.localStorage.__proto__.setItem = jest.fn();
// assertions as usual:
expect(localStorage.setItem).toHaveBeenCalled();
jest.spyOn(window.localStorage.__proto__, 'setItem');
ya da sadece böyle bir sahte paket alırsınız:
https://www.npmjs.com/package/jest-localstorage-mock
yalnızca depolama işlevini değil aynı zamanda mağazanın gerçekten çağrılıp çağrılmadığını test etmenizi sağlar.
undefined
Değerleri (varsa toString()
) işleyen ve null
değer yoksa döndüren daha iyi bir alternatif . Bunu react
v15 ile test ettik redux
veredux-auth-wrapper
class LocalStorageMock {
constructor() {
this.store = {}
}
clear() {
this.store = {}
}
getItem(key) {
return this.store[key] || null
}
setItem(key, value) {
this.store[key] = value
}
removeItem(key) {
delete this.store[key]
}
}
global.localStorage = new LocalStorageMock
removeItem
: developer.mozilla.org/en-US/docs/Web/API/Storage/removeItem
Eğer bir saplama değil, bir sahte arıyorsanız, işte kullandığım çözüm:
export const localStorageMock = {
getItem: jest.fn().mockImplementation(key => localStorageItems[key]),
setItem: jest.fn().mockImplementation((key, value) => {
localStorageItems[key] = value;
}),
clear: jest.fn().mockImplementation(() => {
localStorageItems = {};
}),
removeItem: jest.fn().mockImplementation((key) => {
localStorageItems[key] = undefined;
}),
};
export let localStorageItems = {}; // eslint-disable-line import/no-mutable-exports
Depolama öğelerini kolay başlatma için dışa aktarıyorum. IE Kolayca bir nesneye ayarlayabilirsiniz
Jest + JSDom'un daha yeni sürümlerinde bunu ayarlamak mümkün değildir, ancak localstorage zaten mevcuttur ve üzerinde casusluk yapabilirsiniz:
const setItemSpy = jest.spyOn(Object.getPrototypeOf(window.localStorage), 'setItem');
Bu çözümü github'dan buldum
var localStorageMock = (function() {
var store = {};
return {
getItem: function(key) {
return store[key] || null;
},
setItem: function(key, value) {
store[key] = value.toString();
},
clear: function() {
store = {};
}
};
})();
Object.defineProperty(window, 'localStorage', {
value: localStorageMock
});
Bu kodu setupTest'lerinize ekleyebilirsiniz ve düzgün çalışması gerekir.
Ben typesctipt ile bir projede test etti.
Ne yazık ki, burada bulduğum çözümler benim için işe yaramadı.
Bu yüzden Jest GitHub sorunlarına bakıyordum ve bu konuyu buldum
En çok oylanan çözümler şunlardı:
const spy = jest.spyOn(Storage.prototype, 'setItem');
// or
Storage.prototype.getItem = jest.fn(() => 'bla');
window
veya Storage
tanımlanmamış. Belki de Jest'in eski versiyonudur.
@ Ck4 önerdiği belgelerinlocalStorage
jest olarak kullanılması konusunda açık bir açıklaması vardır . Ancak, sahte işlevler,localStorage
yöntemlerin .
Aşağıda, veri yazma ve okuma için soyut yöntemleri kullanan tepki bileşenimin ayrıntılı örneği,
//file: storage.js
const key = 'ABC';
export function readFromStore (){
return JSON.parse(localStorage.getItem(key));
}
export function saveToStore (value) {
localStorage.setItem(key, JSON.stringify(value));
}
export default { readFromStore, saveToStore };
Hata:
TypeError: _setupLocalStorage2.default.setItem is not a function
Düzeltme:
jest için sahte fonksiyonu aşağıda Ekle (yol: .jest/mocks/setUpStore.js
)
let mockStorage = {};
module.exports = window.localStorage = {
setItem: (key, val) => Object.assign(mockStorage, {[key]: val}),
getItem: (key) => mockStorage[key],
clear: () => mockStorage = {}
};
Snippet'e buradan referans verilir
Typescript ile bir proje için çözmek için burada bazı diğer cevaplar attı. Böyle bir LocalStorageMock oluşturdum:
export class LocalStorageMock {
private store = {}
clear() {
this.store = {}
}
getItem(key: string) {
return this.store[key] || null
}
setItem(key: string, value: string) {
this.store[key] = value
}
removeItem(key: string) {
delete this.store[key]
}
}
Daha sonra, global yerel depolama değişkenine doğrudan erişmek yerine uygulamadaki yerel depolamaya tüm erişim için kullandığım bir LocalStorageWrapper sınıfı oluşturdum. Testler için alaycı sargıya yerleştirmeyi kolaylaştırdı.
describe('getToken', () => {
const Auth = new AuthService();
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Ik1yIEpvc2VwaCIsImlkIjoiNWQwYjk1Mzg2NTVhOTQ0ZjA0NjE5ZTA5IiwiZW1haWwiOiJ0cmV2X2pvc0Bob3RtYWlsLmNvbSIsInByb2ZpbGVVc2VybmFtZSI6Ii9tcmpvc2VwaCIsInByb2ZpbGVJbWFnZSI6Ii9Eb3Nlbi10LUdpci1sb29rLWN1dGUtbnVrZWNhdDMxNnMtMzExNzAwNDYtMTI4MC04MDAuanBnIiwiaWF0IjoxNTYyMzE4NDA0LCJleHAiOjE1OTM4NzYwMDR9.YwU15SqHMh1nO51eSa0YsOK-YLlaCx6ijceOKhZfQZc';
beforeEach(() => {
global.localStorage = jest.fn().mockImplementation(() => {
return {
getItem: jest.fn().mockReturnValue(token)
}
});
});
it('should get the token from localStorage', () => {
const result = Auth.getToken();
expect(result).toEqual(token);
});
});
Bir alay oluşturma ve bunu global
nesneye ekleme
Bu snippet'lerle yerel depolamayı taklit etmeniz gerekiyor
// localStorage.js
var localStorageMock = (function() {
var store = {};
return {
getItem: function(key) {
return store[key] || null;
},
setItem: function(key, value) {
store[key] = value.toString();
},
clear: function() {
store = {};
}
};
})();
Object.defineProperty(window, 'localStorage', {
value: localStorageMock
});
Ve jest yapılandırmasında:
"setupFiles":["localStorage.js"]
Herhangi bir şey sormaktan çekinmeyin.
Aşağıdaki çözüm daha katı TypeScript, ESLint, TSLint ve Prettier yapılandırması ile test için uyumludur { "proseWrap": "always", "semi": false, "singleQuote": true, "trailingComma": "es5" }
:
class LocalStorageMock {
public store: {
[key: string]: string
}
constructor() {
this.store = {}
}
public clear() {
this.store = {}
}
public getItem(key: string) {
return this.store[key] || undefined
}
public setItem(key: string, value: string) {
this.store[key] = value.toString()
}
public removeItem(key: string) {
delete this.store[key]
}
}
/* tslint:disable-next-line:no-any */
;(global as any).localStorage = new LocalStorageMock()
Global.localStorage'ın nasıl güncelleneceği hakkında HT / https://stackoverflow.com/a/51583401/101290
Aynı şeyi Dizeler yazısında yapmak için aşağıdakileri yapın:
Aşağıdaki içeriklere sahip bir dosya kurun:
let localStorageMock = (function() {
let store = new Map()
return {
getItem(key: string):string {
return store.get(key);
},
setItem: function(key: string, value: string) {
store.set(key, value);
},
clear: function() {
store = new Map();
},
removeItem: function(key: string) {
store.delete(key)
}
};
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });
Ardından, Jest yapılandırmalarınızın altındaki package.json dosyasına aşağıdaki satırı eklersiniz
"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",
Veya bu dosyayı localstorage ile alay etmek istediğiniz test vakanıza aktarırsınız.
value + ''
null ve tanımsız değerleri doğru şekilde işlemek için ayarlayıcıda