У меня есть таблица реагирования с событиями click и doubleclick в строках, что потребовало использования таймера для работы обоих событий.
Событие с одним щелчком выбирает строку в состоянии, поэтомуМне пришлось использовать таймер в модульном тесте, чтобы правильно проверить изменение состояния.Затем я снова пытаюсь смоделировать щелчок по строке, но получаю Uncaught [Invariant Violation: Unable to find node on an unmounted component.]
Тест прошел нормально, прежде чем я добавил логику таймера, поэтому я могу только предположить, что компонент как-то размонтирован до того, как произойдет мой обратный вызов таймераcall, даже если я не вызываю done () до обратного вызова.
Может быть, это просто не сработает?
Мой pacakge.json:
"react": "^16.8.6",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.13.1",
"jest": "^22.4.4"
Код, который я пытаюсь проверить:
let timer;
const delay = 200;
// extraneous stuff removed
return {
onClick: e => {
timer = setTimeout(() => {
if (!prevent && rowInfo && rowInfo.row) {
this.setSelectedRecord(rowInfo.original);
this.props.onSelect && this.props.onSelect(rowInfo.original[primaryKey]);
}
prevent = false;
}, delay);
},
onDoubleClick: e => {
clearTimeout(timer);
prevent = true;
if (rowInfo && rowInfo.row) {
this.setSelectedRecord(null);
this.props.onDoubleClick && this.props.onDoubleClick(rowInfo.original[primaryKey]);
}
}
};
Неудачный юнит-тест:
it('selects row on single click', async (done) => {
const mockCallback = jest.fn();
const newProps = {...props, data: data, schema: schema, onSelect: mockCallback};
const wrapper = mount(<QueryRecordsTable {...newProps} />);
const rows = wrapper.find(Tooltip);
// 3 fields * 2 records
expect(rows.length).toEqual(6);
rows.at(0).simulate('click');
setTimeout(() => {
expect(mockCallback.mock.calls[0][0]).toEqual(ID1);
expect((wrapper.state() as any).selectedRecord.ID).toEqual(ID1);
expect(wrapper).toMatchSnapshot();
const rows2 = wrapper.find(Tooltip);
rows2.at(3).simulate('click');
}, 300);
});
Когда вызывается симуляция из обратного вызова, я получаю это:
Error: Uncaught [Invariant Violation: Unable to find node on an unmounted component.]
at reportException (D:\mdm\mdm-ui\node_modules\jsdom\lib\jsdom\living\helpers\runtime-script-errors.js:66:24)
at Timeout.callback [as _onTimeout] (D:\mdm\mdm-ui\node_modules\jsdom\lib\jsdom\browser\Window.js:680:7)
at ontimeout (timers.js:458:11)
at tryOnTimeout (timers.js:296:5)
at Timer.listOnTimeout (timers.js:259:5) { Invariant Violation: Unable to find node on an unmounted component.
at invariant (D:\mdm\mdm-ui\node_modules\react-dom\cjs\react-dom.development.js:55:15)
at findCurrentFiberUsingSlowPath (D:\mdm\mdm-ui\node_modules\react-dom\cjs\react-dom.development.js:4166:7)
at findCurrentHostFiber (D:\mdm\mdm-ui\node_modules\react-dom\cjs\react-dom.development.js:4235:23)
at findHostInstanceWithWarning (D:\mdm\mdm-ui\node_modules\react-dom\cjs\react-dom.development.js:20629:21)
at Object.findDOMNode (D:\mdm\mdm-ui\node_modules\react-dom\cjs\react-dom.development.js:21138:14)
at mapper (D:\mdm\mdm-ui\node_modules\enzyme-adapter-react-16\build\ReactSixteenAdapter.js:304:61)
at _nodeToHostNode (D:\mdm\mdm-ui\node_modules\enzyme-adapter-react-16\build\ReactSixteenAdapter.js:313:10)
at ReactSixteenAdapter.nodeToHostNode (D:\mdm\mdm-ui\node_modules\enzyme-adapter-react-16\build\ReactSixteenAdapter.js:906:21)
at Object.simulateEvent (D:\mdm\mdm-ui\node_modules\enzyme-adapter-react-16\build\ReactSixteenAdapter.js:532:31)
at ReactWrapper.<anonymous> (D:\mdm\mdm-ui\node_modules\enzyme\build\ReactWrapper.js:953:29)
at ReactWrapper.single (D:\mdm\mdm-ui\node_modules\enzyme\build\ReactWrapper.js:1720:25)
at ReactWrapper.simulate (D:\mdm\mdm-ui\node_modules\enzyme\build\ReactWrapper.js:952:21)
at setTimeout (D:\mdm\mdm-ui\src\components\SelectRecords\__tests__\QueryRecordsTable.test.tsx:67:25)
at Timeout.callback [as _onTimeout] (D:\mdm\mdm-ui\node_modules\jsdom\lib\jsdom\browser\Window.js:678:19)
at ontimeout (timers.js:458:11)
at tryOnTimeout (timers.js:296:5)
at Timer.listOnTimeout (timers.js:259:5) name: 'Invariant Violation', framesToPop: 1 }