[英]Jest to Test that a Component Cleared the Session Storage
我正在嘗試測試一個組件,看看我是否可以清除 session 存儲。 我正在使用 Jest 進行測試。 我有一條線不想通過測試。 我不知道如何確保它正在測試 sessionStorage 是清楚的。 我已經嘲笑了它,並且 function 可以工作,但是測試仍然失敗了一行。 有誰知道如何讓這條線通過?
LogOutForDisagreement.js
import React from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import ClipboardClip from './../ClipboardClip';
const store = require('store2');
function LogOutForDisagreement(props) {
const handleClick = (e) => {
e.preventDefault();
props.onChange(
props.props.user = {
loggedIn: false,
email: '',
password: '',
firstName: ''
},
);
store.clearAll();
};
return (
<div id="logOutForDisagreementClipboard" className={props.className}>
<Form className="form">
<ClipboardClip />
<div className="centeredPaper">
<p>Sorry, you must agree to our privacy policy to access the site. You must now log out and log back in to agree to the terms.</p>
<Button id="logOutForDisagreement" type="" onClick={handleClick}>
Log Out
</Button>
</div>
</Form>
</div>
);
}
export default LogOutForDisagreement;
測試 LogOutForDisagreement.test.js
import React from 'react';
import { render, fireEvent, cleanup } from '@testing-library/react';
import toJson from 'enzyme-to-json';
import LogOutForDisagreement from './LogOutForDisagreement';
import store from 'store2';
const fakeLocalStorage = (function() {
let storage = {"firstName": "Nathaniel", "email":"exampleFirstName.exampleLastName@example.com","timeOfLogin":"1657937069720","id":"bee89ba2-da07-4712-acd2-e8236660bb13"};
return {
getItem: function(key) {
return storage[key] || null;
},
setItem: function(key, value) {
storage[key] = value.toString();
},
removeItem: function(key) {
delete storage[key];
},
clearAll: function() {
storage = {};
},
getAll() {
return storage;
},
};
})();
describe('Test the log out for disagreement button', () =>{
beforeAll(() => {
Object.defineProperty(window, 'sessionStorage', {
value: fakeLocalStorage,
});
});
it('renders correctly enzyme and has onclick', () => {
const { getByText } = render(<LogOutForDisagreement />);
fireEvent.click(getByText("Log Out"));
window.sessionStorage.clearAll();
const allItems = window.sessionStorage.getAll();
console.log("These are all the items in sessionStorage: " + JSON.stringify(allItems));
console.log("These are the number of items: " + Object.keys(allItems).length);
expect(Object.keys(allItems).length).toBe(0);
expect(toJson(getByText)).toMatchSnapshot();
});
});
我得到以下信息:
--------------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------------------|---------|----------|---------|---------|-------------------
All files | 83.33 | 100 | 100 | 83.33 |
LogOutForDisagreement.js | 83.33 | 100 | 100 | 83.33 | 19
--------------------------|---------|----------|---------|---------|-------------------
所以第19行基本上是window.sessionStorage.clearAll();
,但我不知道如何測試它。 我有幾個問題:
store.clearAll();
那實際上是這樣做的嗎?編輯:所以,現在我正在嘗試使用 jest-localstorage-mock,但我不斷收到以下錯誤:
● Test the log out for disagreement button › renders correctly enzyme and has onclick
ReferenceError: dispatch is not defined
85 | //expect(sessionStorage.clear).toHaveBeenCalledTimes(1);
86 |
> 87 | dispatch(action.reset());
| ^
88 | expect(sessionStorage.clear).toHaveBeenCalledTimes(1);
89 | expect(sessionStorage.__STORE__).toEqual({}); // check store values
90 | expect(sessionStorage.length).toBe(0); // or check length
此調用應該檢查商店現在是否已清除,但我仍然顯示該行沒有被覆蓋:
src/components/privacyPolicyComponents | 24.44 | 0 | 21.05 | 24.44 |
LogOutForDisagreement.js | 87.5 | 100 | 100 | 87.5 | 19
我按照 package 中的說明進行操作,但我仍然不知道出了什么問題。
需要在測試文件中導入package嗎? 我找不到辦法做到這一點。 我把更新的文件放在下面:
LogOutForDisagreement.js
import React from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import ClipboardClip from './../ClipboardClip';
const store = require('store2');
function LogOutForDisagreement(props) {
const handleClick = (e) => {
e.preventDefault();
props.onChange(
props.props.user = {
loggedIn: false,
email: '',
password: '',
firstName: ''
},
);
store.clearAll();
};
return (
<div id="logOutForDisagreementClipboard" className={props.className}>
<Form className="form">
<ClipboardClip />
<div className="centeredPaper">
<p>Sorry, you must agree to our privacy policy to access the site. You must now log out and log back in to agree to the terms.</p>
<Button id="logOutForDisagreement" type="" onClick={handleClick}>
Log Out
</Button>
</div>
</Form>
</div>
);
}
export default LogOutForDisagreement;
LogOutForDisagreement.test.js
import React from 'react';
import { render, fireEvent, cleanup } from '@testing-library/react';
import toJson from 'enzyme-to-json';
import LogOutForDisagreement from './LogOutForDisagreement';
import store from 'store2';
//import { dispatch, action, reset } from 'jest-localstorage-mock';
let props = {
props:
{
user: {
loggedIn: false,
email: 'email@example.com',
password: '0cc3dd4ad221f83270f876908064fa67d43407aa4bd580731b30c58c4fe2d8de00464107e5a143594068461af21ece9fb542e2f254b6f895eea6a6627f4f7c438a42fb18af7f539c4be2456661a5beec4a561f9443988182445b3952a5d9321a2d725b24b151f79a2806432c848b0b0c02576676e3a5c6f0661b4e318ca4f3e134d066808fab8fdd5322ed5cf5ad68aae43254a8fefdb69809c1bfdc07fe0365f38baa424d0c059c3a9fbff1f3525dae410740b9719929ef3f34235da519591f0410a08438132600fa802079b8d6f372f6dc439eb1b100aed28bb55cc3c6dc8982644940bd506278943fa8e430836cb874283e9f4438aac04a817f86bd1606036f03d196a211bdd91ac683d4ec63fcd503aa97b53d5c2571d39855b2be5f77be80a7f767271c8789aec26c66530c22387007c704f96b1a76a47e8e13fb263a0a6b24b2959495d34b47e03bcb95e8af13b555c5c403ec01427182afa1bae35ff81224b051fde7a61bd9044ed74042444a05e06186eedacc38c0128ff7d70c',
firstName: 'FirstName'
},
className: "logOutForDisagreement"
}
};
describe('Test the log out for disagreement button', () => {
beforeAll(() => {
store.setAll({ "firstName": "FirstName", "email": "email@example.com", "timeOfLogin": "1657937069720", "id": "0cc3dd4ad221f83270f876908064fa67d43407aa4bd580731b30c58c4fe2d8de00464107e5a143594068461af21ece9fb542e2f254b6f895eea6a6627f4f7c438a42fb18af7f539c4be2456661a5beec4a561f9443988182445b3952a5d9321a2d725b24b151f79a2806432c848b0b0c02576676e3a5c6f0661b4e318ca4f3e134d066808fab8fdd5322ed5cf5ad68aae43254a8fefdb69809c1bfdc07fe0365f38baa424d0c059c3a9fbff1f3525dae410740b9719929ef3f34235da519591f0410a08438132600fa802079b8d6f372f6dc439eb1b100aed28bb55cc3c6dc8982644940bd506278943fa8e430836cb874283e9f4438aac04a817f86bd1606036f03d196a211bdd91ac683d4ec63fcd503aa97b53d5c2571d39855b2be5f77be80a7f767271c8789aec26c66530c22387007c704f96b1a76a47e8e13fb263a0a6b24b2959495d34b47e03bcb95e8af13b555c5c403ec01427182afa1bae35ff81224b051fde7a61bd9044ed74042444a05e06186eedacc38c0128ff7d70c" });
});
it('renders correctly enzyme and has onclick', () => {
const { getByText } = render(<LogOutForDisagreement id="logOutForDisagreementClipboard" className={props.className} />);
fireEvent.click(getByText("Log Out"));
dispatch(action.reset());
expect(sessionStorage.clear).toHaveBeenCalledTimes(1);
expect(sessionStorage.__STORE__).toEqual({}); // check store values
expect(sessionStorage.length).toBe(0); // or check length
expect(Object.keys(allItems).length).toBe(0);
expect(toJson(getByText)).toMatchSnapshot();
});
});
編輯:我包括index.d.ts
的 index.d.ts 的內容。 如果您想查看完整的 package,它位於 npm 注冊表: https://www.npmjs.com/package/store2/ 。 我還更新了上面的最后一個文件,並包含了jest-localstorage-mock
的配置,但是我仍然收到關於 dispatch not defined 的錯誤,但是當我在dispatch
之前添加store
時,我可以得到 go 的錯誤,所以它是store.dispatch
,但隨后我收到另一個關於未定義操作的錯誤。 我想出了如何定義action
,但后來我收到一個關於reset
的錯誤,我無法到達 go 。
index.d.ts
export interface StoredData {
[key: string]: any;
}
export type Replacer = (key: any, value: any) => string | String[] | number[];
export type Reviver = (key: string, value: any) => any;
export type EachFn = (key: any, data: any) => false | any;
export type TransactFn = (data: any) => any | undefined;
type BaseSet = (key: any, data: any) => any;
type BaseGet = (key: any) => any;
type BaseSetAll = (obj: Object) => StoredData;
type BaseGetAll = () => StoredData;
type BaseTransact = (fn: EachFn, value?: any) => StoredData;
type BaseClear = (clear: false) => StoreBase;
export type Base = BaseSet & BaseGet & BaseSetAll & BaseGetAll & BaseTransact & BaseClear;
export interface StoreAPI {
clear(): StoreBase;
clearAll(): StoreBase;
each(callback: EachFn): StoreBase;
get(key: any, alt?: any|Reviver): any;
getAll(fillObj?: StoredData): StoredData;
has(key: any): boolean;
isFake(force?: boolean): boolean;
keys(fillList?: string[]): string[];
namespace(namespace: string, noSession?: true): StoreType;
remove(key: any, alt?: any|Reviver): any;
set(key: any, data: any, overwrite?: boolean|Replacer): any;
setAll(data: Object, overwrite?: boolean|Replacer): StoredData;
add(key: any, data: any): any;
size(): number;
transact(key: any, fn: TransactFn, alt?: any|Reviver): StoreBase;
area(id: string, area: Storage): StoreBase
}
export type StoreBase = StoreAPI & Base;
export type StoreType = StoreBase & {
local: StoreBase;
session: StoreBase;
page: StoreBase;
};
declare const store: StoreType
export default store
package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
...
},
"devDependencies": {
"jest-localstorage-mock": "^2.4.22"
},
"jest": {
"resetMocks": false
}
}
setupTests.js
require('jest-localstorage-mock');
FWIW @Sandog,我嘗試了您使用的方法,但無法使其正常工作,盡管我的用例與您的用例有些不同。 當用戶選擇不同的投資組合時,我們會清除(graphQL)緩存,以便新的投資組合可以使用(所有數據更改)。 因此,對於我的測試,我需要做的就是設置並確保實際調用了client.resetStore()
function。 我是這樣做的:
it('responds to ribbonName clicks', async () => {
// setup the mocked resetStore() and test it.
// Things didn't work as expected sometimes
// so I wanted to make sure it was setup properly :=))
const mockResetStore = jest.fn();
client.resetStore = mockResetStore;
expect(mockResetStore).not.toHaveBeenCalled();
// setup and issue the call the EntityRibbon component
const myInitialState = {...initialState};
myInitialState.entitiesList.push(...testEntities);
const providerValue = {state: myInitialState, dispatch: () => {}};
await render(
<AppContext.Provider value={providerValue}>
<EntityRibbon />
</AppContext.Provider>
);
// Another check to make sure the mock is working correctly
expect(mockResetStore).not.toHaveBeenCalled();
// find and click the portfolio names on the EntityRibbon
R.pluck('ribbonName', testEntities).forEach(async ribbonName => {
const ribbonElement = await screen.getByText(ribbonName);
expect(ribbonElement).toBeInTheDocument();
await fireEvent.click(ribbonElement);
// Ensure that client.resetStore() was actually called as expected
expect(client.resetStore).toHaveBeenCalled();
});
})
也許這會有所幫助...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.