javascript - jest/enzyme 测试因导入服务而失败
问题描述
我有一个开玩笑的测试,它正在测试一个浅渲染的组件:
import * as React from 'react';
import { shallow } from 'enzyme';
import MFASection from './MFASection';
test('molecules/MFASection mounts', () => {
const component = shallow(<MFASection />);
expect(component.exists()).toBe(true);
});
它失败的地方在这里:
TypeError: Cannot read property 'then' of undefined
componentDidMount(): () => Promise<any> {
> 22 | return svc.getMe()
| ^
23 | .then((res) => {
24 | this.setState({ enabledMFA: res.data.mfa_enabled });
25 | });
在组件处,svc
正在被导入并用于componentDidMount
import svc from 'constants/svc';
....
componentDidMount(): () => Promise<any> {
return svc.getMe()
.then((res) => {
this.setState({ enabledMFA: res.data.mfa_enabled });
});
}
其他任何东西都只是我写的自定义服务:
import Svc from '@spring/svc';
import { getOrCreateStore } from 'utils/redux/wrapper';
export default new Svc(process.env.AUTH_API_DOMAIN, getOrCreateStore());
我不确定如何通过此测试。测试本身有什么我遗漏的吗?
解决方案
这里有两个解决方案:
jest.spyOn
setImmediate
例如
index.tsx
:
import React, { Component } from 'react';
import svc from './contants/svc';
class MFASection extends Component<any, any> {
constructor(props) {
super(props);
this.state = {
enabledMFA: true
};
}
componentDidMount() {
svc.getMe().then(res => {
console.log(res);
this.setState({ enabledMFA: res.data.mfa_enabled });
});
}
render() {
return <div>enabledMFA: {this.state.enabledMFA ? '1' : '2'}</div>;
}
}
export default MFASection;
index.spec.tsx
:
import React from 'react';
import { shallow } from 'enzyme';
import MFASection from '.';
import svc from './contants/svc';
describe('MFASection', () => {
afterEach(() => {
jest.restoreAllMocks();
});
test('molecules/MFASection mounts', done => {
const mRepsonse = { data: { mfa_enabled: false } };
let successHandler;
const getMeSpy = jest.spyOn(svc, 'getMe').mockImplementation((): any => {
const mThen = jest.fn().mockImplementationOnce((onfulfilled: any): any => {
successHandler = onfulfilled;
});
return { then: mThen };
});
const wrapper = shallow(<MFASection></MFASection>);
expect(wrapper.exists()).toBe(true);
expect(wrapper.state('enabledMFA')).toBeTruthy();
successHandler(mRepsonse);
expect(wrapper.text()).toBe('enabledMFA: 2');
expect(getMeSpy).toBeCalledTimes(1);
done();
});
test('molecules/MFASection mounts - 2', done => {
const mRepsonse = { data: { mfa_enabled: false } };
const getMeSpy = jest.spyOn(svc, 'getMe').mockResolvedValueOnce(mRepsonse);
const wrapper = shallow(<MFASection></MFASection>);
expect(wrapper.exists()).toBe(true);
expect(wrapper.state('enabledMFA')).toBeTruthy();
setImmediate(() => {
expect(wrapper.text()).toBe('enabledMFA: 2');
done();
});
expect(getMeSpy).toBeCalledTimes(1);
});
});
contants/svc.ts
:
const getOrCreateStore = () => {};
class Svc {
constructor(domain, getOrCreateStore) {}
public async getMe() {
return { data: { mfa_enabled: true } };
}
}
export default new Svc(process.env.AUTH_API_DOMAIN, getOrCreateStore());
带有覆盖率报告的单元测试结果:
PASS src/stackoverflow/58648463/index.spec.tsx (5.062s)
MFASection
✓ molecules/MFASection mounts (87ms)
✓ molecules/MFASection mounts - 2 (18ms)
console.log src/stackoverflow/58648463/index.tsx:1573
{ data: { mfa_enabled: false } }
console.log src/stackoverflow/58648463/index.tsx:1573
{ data: { mfa_enabled: false } }
------------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
------------------------|----------|----------|----------|----------|-------------------|
All files | 95.24 | 100 | 88.89 | 94.74 | |
58648463-todo | 100 | 100 | 100 | 100 | |
index.tsx | 100 | 100 | 100 | 100 | |
58648463-todo/contants | 83.33 | 100 | 75 | 83.33 | |
svc.ts | 83.33 | 100 | 75 | 83.33 | 7 |
------------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 6.965s, estimated 13s
源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58648463
推荐阅读
- html - 将页脚推到底部而不将鼠标悬停在信息上
- c++ - GTest - 不同类型的参数化测试
- arrays - 如何从数组中提取 Powershell validatescript 参数?
- c - 读取 SELECT'ed 值并将其作为 int 存储在 C 中
- reactjs - 如何将图标添加到 Material UI Select 选项?
- python - 将多个数据框列展平为一个
- php - 如何为具有混合列值的关联数组生成分组依据和平均报告
- rest - 如何使用 Moodle REST API 调用 mod_data_add_entry(和参数)?
- bixby - How can I have bixby repeat an action but forget previous inputs?
- node.js - 如何将 findById() 用于猫鼬中的嵌套数组?