답변:
@chiedo의 훌륭한 솔루션
그러나 우리는 ES2015 구문을 사용 하며이 방법으로 작성하는 것이 조금 더 깨끗하다고 느꼈습니다.
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
그래서 내 테스트 에서을 사용 했기 때문에 테스트가 실패했습니다 not.toBeDefined()
. 다시 작동하게 @Chiedo 솔루션
https://groups.google.com/forum/#!topic/jestjs/9EPhuNWVYTg의 도움으로 알아 냈습니다.
다음 내용으로 파일을 설정하십시오.
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 });
그런 다음 Jest 구성 아래 package.json에 다음 줄을 추가하십시오.
"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",
"setupFiles": [...]
잘 작동합니다. 배열 옵션을 사용하면 모의 파일을 별도의 파일로 분리 할 수 있습니다. 예 :"setupFiles": ["<rootDir>/__mocks__/localStorageMock.js"]
getItem
특정 키에 대해 데이터가 설정되지 않은 경우 브라우저에서 반환되는 값 과 약간 다릅니다. getItem("foo")
설정되지 않은 경우 호출 하면 예를 들어 null
브라우저에서 반환 되지만 undefined
이 모형으로 인해 테스트 중 하나가 실패했습니다. 나를위한 간단한 해결책 store[key] || null
은 getItem
기능 으로 돌아 오는 것이 었습니다
localStorage['test'] = '123'; localStorage.getItem('test')
create-react-app를 사용하는 경우 문서에 설명되어있는 더 간단하고 간단한 솔루션이 있습니다 .
src/setupTests.js
이것을 작성 하여 넣습니다.
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
clear: jest.fn()
};
global.localStorage = localStorageMock;
아래의 코멘트에서 Tom Mertz의 공헌 :
그런 다음 다음과 같은 작업을 수행하여 localStorageMock의 기능이 사용되는지 테스트 할 수 있습니다
expect(localStorage.getItem).toBeCalledWith('token')
// or
expect(localStorage.getItem.mock.calls.length).toBe(1)
호출되었는지 확인하려는 경우 테스트 내부. https://facebook.github.io/jest/docs/en/mock-functions.html을 확인 하십시오
localStorage
코드에서 사용 하는 것을 자동으로 조롱 합니다. (만약 당신이 create-react-app
자연스럽게 제공하는 모든 자동 스크립트 를 사용한다면 )
expect(localStorage.getItem).toBeCalledWith('token')
또는 expect(localStorage.getItem.mock.calls.length).toBe(1)
내부에서 무언가를 수행하여 localStorageMock의 기능이 사용 되는지 테스트 할 수 있습니다. 확인 facebook.github.io/jest/docs/en/mock-functions.html
localStorage
않습니까? "스 필러"가 다른 테스트로 들어 가지 않도록 각 테스트 후 스파이를 재설정하고 싶지 않습니까?
현재 (Oct '19) localStorage는 평소와 같이 jest가 조롱하거나 감시 할 수 없으며 create-react-app 문서에 설명되어 있습니다. 이것은 jsdom의 변경으로 인한 것입니다. 당신은 그것에 대해 읽을 수있는 농담 과 jsdom 이슈 트래커.
이 문제를 해결하려면 대신 프로토 타입을 감시 할 수 있습니다.
// 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');
또는 다음과 같이 모의 패키지를 가져 가십시오.
https://www.npmjs.com/package/jest-localstorage-mock
저장소 기능뿐만 아니라 저장소가 실제로 호출되었는지 테스트 할 수도 있습니다.
undefined
값 을 처리하고 (없는 toString()
) null
값이 존재하지 않으면 반환 하는 더 나은 대안입니다 . react
v15로 이것을 테스트 redux
하고redux-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
스텁이 아닌 모의를 찾고 있다면 여기에 내가 사용하는 솔루션이 있습니다.
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
쉽게 초기화 할 수 있도록 저장소 항목을 내 보냅니다. IE 쉽게 객체로 설정할 수 있습니다
최신 버전의 Jest + JSDom에서는이를 설정할 수 없지만 로컬 저장소는 이미 사용 가능하므로 다음과 같이 감시 할 수 있습니다.
const setItemSpy = jest.spyOn(Object.getPrototypeOf(window.localStorage), 'setItem');
github 에서이 솔루션을 찾았습니다.
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
});
이 코드를 setupTests에 삽입하면 정상적으로 작동합니다.
typesctipt가있는 프로젝트에서 테스트했습니다.
@ ck4가 제안한 문서 는 jest 에서 사용 localStorage
하는 것에 대한 명확한 설명을 제공 합니다. 그러나 모의 함수가 localStorage
메소드 를 실행하지 못했습니다 .
아래는 데이터를 쓰고 읽는 추상적 인 방법을 사용하는 반응 구성 요소의 자세한 예입니다.
//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 };
오류:
TypeError: _setupLocalStorage2.default.setItem is not a function
수정 :
농담에 대한 모의 기능 아래에있는 추가 (경로 : .jest/mocks/setUpStore.js
)
let mockStorage = {};
module.exports = window.localStorage = {
setItem: (key, val) => Object.assign(mockStorage, {[key]: val}),
getItem: (key) => mockStorage[key],
clear: () => mockStorage = {}
};
Typescript가있는 프로젝트 에서이 문제를 해결하기 위해 다른 답변을 생략했습니다. 다음과 같이 LocalStorageMock을 만들었습니다.
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]
}
}
그런 다음 전역 로컬 스토리지 변수에 직접 액세스하는 대신 앱의 로컬 스토리지에 대한 모든 액세스에 사용하는 LocalStorageWrapper 클래스를 만들었습니다. 테스트를 위해 랩퍼에 모의를 쉽게 설정할 수있게했습니다.
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);
});
});
모형을 만들어 global
객체에 추가
이 스 니펫으로 로컬 저장소를 조롱해야합니다.
// 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
});
그리고 jest 설정에서 :
"setupFiles":["localStorage.js"]
무엇이든 물어보세요.
다음 솔루션은보다 엄격한 TypeScript, ESLint, TSLint 및 Prettier 구성을 사용한 테스트와 호환됩니다 { "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를 업데이트하는 방법에 대한 HT / https://stackoverflow.com/a/51583401/101290
Typescript에서 동일한 작업을 수행하려면 다음을 수행하십시오.
다음 내용으로 파일을 설정하십시오.
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 });
그런 다음 Jest 구성 아래 package.json에 다음 줄을 추가하십시오.
"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",
또는 로컬 스토리지를 모방하려는 테스트 케이스에서이 파일을 가져옵니다.
value + ''
올바르게 핸들 널 (null)과 정의되지 않은 값으로 세터에