Я искал решение, позволяющее работать $.bind
и $.unbind
без проблем в динамически добавленных элементах.
Поскольку on () делает трюк для присоединения событий, чтобы создать фальшивую отвязку на тех, к которым я пришел:
const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );
// unbind the click
$('body').on('click', 'button.send', function(){} );
Здесь есть две проблемы
setData
setData
вызывается в обратном вызове Promise
.
Как только Promise
разрешается, все обратные вызовы, ожидающие его, ставятся в очередь в очереди PromiseJobs . Все ожидающие задания в очереди PromiseJobs запускаются после завершения текущего сообщения и до начала следующего сообщения .
В этом случае текущее работающее сообщение - это ваш тест, поэтому ваш тест завершается до того, как обратный вызов Promise
сможет его выполнить, и setData
не вызывается до после вашего теста завершается.
Вы можете исправить это, используя что-то вроде setImmediate
, чтобы отложить ваши утверждения до тех пор, пока не будут запущены обратные вызовы в PromiseJobs.
Похоже, вам также нужно вызвать component.update()
для повторного рендеринга компонента с новым состоянием. (Я предполагаю, что это потому, что изменение состояния происходит вне act
, поскольку нет никакого способа обернуть этот код обратного вызова в act
.)
Все вместе, рабочий тест выглядит например:
it('should render a proper table data', done => {
const mock = new MockAdapter(axios);
mock.onGet('/path/to/api').reply(200, response.data);
const component = mount(<SalesPlanTable />);
setImmediate(() => {
component.update();
console.log(component.debug());
done();
});
});
Предупреждение вызывается обновлениями состояния компонента, который случиться за пределами act
.
Изменения состояния, вызванные асинхронными вызовами к setData
, инициированными функцией useEffect
, всегда будут происходить за пределами act
.
Вот очень простой тест, демонстрирующий это поведение:
import React, { useState, useEffect } from 'react';
import { mount } from 'enzyme';
const SimpleComponent = () => {
const [data, setData] = useState('initial');
useEffect(() => {
setImmediate(() => setData('updated'));
}, []);
return (<div>{data}</div>);
};
test('SimpleComponent', done => {
const wrapper = mount(<SimpleComponent/>);
setImmediate(done);
});
Когда я искал дополнительную информацию, я наткнулся на enzyme
выпуск № 2073 , открытый всего 10 часов назад. говорить об этом же поведении.
Я добавил вышеуказанный тест в комментарий , чтобы помочь разработчикам enzyme
решить эту проблему.