【发布时间】:2019-05-15 23:01:28
【问题描述】:
Here是这个问题的repo,如果你想直接复现的话。
我有一个新创建的 react-native 项目(我认为这个问题是 React 还是 React-Native 并不重要)。我只有一个组件App.js:
import React, { Component } from 'react';
import { View } from 'react-native';
import actions from './actions';
export class App extends Component {
async componentDidMount() {
console.log('In CDM');
await actions.funcOne();
await actions.funcTwo();
console.log('Finished CDM');
}
render() {
return <View />;
}
}
这是该组件从actions.js 导入的两个函数:
const funcOne = async () => {
console.log('One');
};
const funcTwo = async () => {
console.log('Two');
};
export default { asyncOne: funcOne, asyncTwo: funcTwo };
这是我写的一个测试:
import React from 'react';
import { App } from '../App';
import renderer from 'react-test-renderer';
import actions from '../actions';
const spyOne = jest.spyOn(actions, 'funcOne');
const spyTwo = jest.spyOn(actions, 'funcTwo');
describe('App ', () => {
test('does async stuff in expected order', async () => {
console.log('Starting test');
const tree = await renderer.create(<App />);
console.log('About to expect');
expect(spyOne).toHaveBeenCalled();
console.log('Expect one to have been called');
expect(spyTwo).toHaveBeenCalled();
console.log('Expect two to have been called');
expect(tree).toMatchSnapshot();
});
});
可以看出,第二个expect 断言在funcTwo 函数在componentDidMount 中执行之前被调用。
我实际上想要完成的是我有一个更复杂的组件,它在componentDidMount 中执行一个异步函数(例如进行 API 调用)。我希望我的测试创建组件树,并断言组件确实调用了相关函数。
我实际上找到了一个“解决方案”(它使我的测试通过并且console.logs以正确的顺序出现,但我不明白它为什么起作用。解决方案是在测试中添加await (() => new Promise(setImmediate))();行在 await renderer.create 行之后的文件。
**所以,我不只想要一个解决方案(尽管如果您有理想的解决方案,请提供)。我想知道这里发生了什么,为什么原始代码不能按预期工作? **
【问题讨论】:
标签: reactjs react-native jestjs