Здесь - это репозиторий для этого вопроса, если вы хотите напрямую воспроизвести.
У меня есть недавно созданный реактивно-нативный проект (думаю, что для этого вопроса не важно, является ли он 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();
});
});
Вот результат запуска теста:
![enter image description here](https://i.stack.imgur.com/T7z7C.png)
Как видно, второе утверждение expect
вызывается до того, как функция funcTwo
выполняется в componentDidMount
.
Что я на самом деле пытаюсь сделать, так это то, что у меня есть гораздо более сложный компонент, который выполняет асинхронную функцию (которая, например, выполняет вызовы API) в componentDidMount
. Я хочу, чтобы мой тест создал дерево компонентов, и утверждаю, что компонент действительно выполнял вызовы соответствующих функций.
Я на самом деле нашел «решение» (оно заставляет мои тесты пройти, и console.logs появляются в правильном порядке, но я не понимаю, почему это работает. Решение состоит в том, чтобы добавить строку await (() => new Promise(setImmediate))();
в тесте файл сразу после строки с await renderer.create
.
** Итак, я не хочу только решение (хотя, если у вас есть идеальное решение, пожалуйста, предоставьте его). Я хочу знать, что здесь происходит, почему оригинальный код не работает должным образом? **