我有一个开玩笑的测试,测试的是浅层渲染的组件:
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());
我不确定如何通过此测试。测试本身有什么我缺少的东西吗?
答案 0 :(得分:0)
以下是两种解决方案:
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