javascript - 如何用 Jest 测试 document.eventListener
问题描述
我有事件监听器,它将调用一个处理身份验证的函数。我想测试如果该函数接收到错误的数据,它将返回一个数据,如果没有,将返回另一个数据。
但我不明白如何模拟该功能并对此做出期望。
那是听众:
window.addEventListener('message', authentication, false);
我想根据结果做出期望的功能:
export function* authentication({ data }) {
// Data structure {
// action: 'authentication',
// id: '7293847829109932,
// displayName: 'User Name',
// avatar: 'https://steamcommunity.com/images/user.png',
// access: 'access_token_string',
// refresh: 'refresh_token_string',
// }
if (data.action === 'authentication') {
localStorage.setItem('dualbits:access', data.access);
localStorage.setItem('dualbits:refresh', data.refresh);
}
// Will dispatch the success action if the data is correct
yield put(signInSuccess(data));
}
到目前为止所做的是模拟窗口全局变量和方法 addEventListener。我做到了这个期望:
expect(window.addEventListener).toHaveBeenCalledWith(
'message',
authentication,
false
);
解决方案
您可以使用mockFn.mockImplementationOnce(fn)来模拟window.addEventListener
方法并控制事件处理程序(authentication
您的案例的功能)的执行。
例如
index.js
:
export function* authentication({ data }) {
if (data.action === 'authentication') {
localStorage.setItem('dualbits:access', data.access);
localStorage.setItem('dualbits:refresh', data.refresh);
}
yield 'dispatch action';
}
export function main() {
window.addEventListener('message', authentication, false);
}
index.test.js
:
import { main } from '.';
const mLocalStorage = {
_storage: {},
getItem: jest.fn((key) => {
return mLocalStorage._storage[key];
}),
setItem: jest.fn((key, value) => {
mLocalStorage._storage[key] = value;
}),
};
Object.defineProperty(window, 'localStorage', {
value: mLocalStorage,
});
describe('61142462', () => {
it('should save data into local storage', () => {
let rval;
jest.spyOn(window, 'addEventListener').mockImplementationOnce((event, handler, options) => {
const gen = handler({ data: { action: 'authentication', access: '123', refresh: 'abc' } });
rval = gen.next().value;
});
main();
expect(rval).toBe('dispatch action');
expect(window.addEventListener).toBeCalledWith('message', expect.any(Function), false);
expect(mLocalStorage.setItem).toBeCalledWith('dualbits:access', '123');
expect(mLocalStorage.setItem).toBeCalledWith('dualbits:refresh', 'abc');
});
it('should not save data into local storage', () => {
let rval;
jest.spyOn(window, 'addEventListener').mockImplementationOnce((event, handler, options) => {
const gen = handler({ data: undefined });
rval = gen.next().value;
});
// You can do the rest of part of this test case
});
});
带有覆盖率报告的单元测试结果:
PASS stackoverflow/61142462/index.test.js (8.196s)
61142462
✓ should save data into local storage (7ms)
✓ should not save data into local storage
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 50 | 100 | 100 |
index.js | 100 | 50 | 100 | 100 | 2
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 9.536s
源代码:https ://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61142462
推荐阅读
- python - 当某些模块以 Cyton 格式提供时,pyreverse 是否有效?(*.so 文件)
- node.js - gulp 4,如何让我的 gulpfile.js 工作?
- javascript - 我无法获得此类的价值
- c# - 反射:获取/设置属性的PropertyType的属性值
- java - 使用 SQL 子查询计算表中的行数并根据结果通过/失败 java 测试
- font-family - Chrome 移动设备上的字体系列选择不一致
- android - 在约束布局中使用 NestedScrollView 的问题
- git - 如何为 github 和 bitbucket 使用不同的全局电子邮件?
- python - 为什么softmax交叉熵损失在张量流中永远不会给出零值?
- c# - 如何在 C# 中构建 TimePicker.TimeChanged 事件?