我使用jest来使用快照测试。
我遇到了react-test-renderer中的一个错误,Invariant Violation:getNodeFromInstance:无效的参数。
复制错误的最小代码:
import React from 'react';
import DateTime from 'react-datetime';
import CalendarContainer from 'react-datetime/src/CalendarContainer';
export default class CalendarTimer extends DateTime {
render() {
return ( <div className = "rdtPicker" >
<CalendarContainer view = {
this.state.currentView
}/>
</div>
);
}
}
这是测试规范文件
import React from 'react';
import renderer from 'react-test-renderer';
import CalendarTimer from 'components/Input/CalendarTimer';
describe('CalendarTimer', () => {
it('rendered Calendar', () => {
const calendarTimer = renderer.create( <
CalendarTimer / >
);
expect(calendarTimer).toMatchSnapshot();
});
});
错误:
● CalendarTimer › rendered Calendar
Invariant Violation: getNodeFromInstance: Invalid argument.
at invariant (node_modules/fbjs/lib/invariant.js:44:15)
at Object.getNodeFromInstance (node_modules/react-dom/lib/ReactDOMComponentTree.js:162:77)
at Object.findDOMNode (node_modules/react-dom/lib/findDOMNode.js:49:41)
at componentDidMount (node_modules/react-onclickoutside/index.js:153:40)
at chainedFunction [as componentDidMount] (node_modules/create-react-class/factory.js:617:11)
at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:265:25
at measureLifeCyclePerf (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:75:12)
at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:264:11
at CallbackQueue.notifyAll (node_modules/react-test-renderer/lib/CallbackQueue.js:76:22)
at ReactTestReconcileTransaction.close (node_modules/react-test-renderer/lib/ReactTestReconcileTransaction.js:36:26)
at ReactTestReconcileTransaction.closeAll (node_modules/react-test-renderer/lib/Transaction.js:206:25)
at ReactTestReconcileTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:153:16)
at batchedMountComponentIntoNode (node_modules/react-test-renderer/lib/ReactTestMount.js:69:27)
at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:140:20)
at Object.batchedUpdates (node_modules/react-test-renderer/lib/ReactDefaultBatchingStrategy.js:62:26)
at Object.batchedUpdates (node_modules/react-test-renderer/lib/ReactUpdates.js:97:27)
at Object.render (node_modules/react-test-renderer/lib/ReactTestMount.js:125:18)
at Object.<anonymous> (tests/components/Input/CalendarTimer_spec.js:8:53)
at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
at process._tickCallback (internal/process/next_tick.js:103:7)
有人可以指出我做错了什么,并指导我修复它。
答案 0 :(得分:2)
讨论了相关问题here
如前所述,这是按预期发生的,因为
React测试渲染器未与React DOM耦合。它无法“猜测”您的组件依赖哪些DOM API。您需要自己模拟节点,如15.4.0发行说明中所述。我希望这有帮助!
您可以看到您的包react-datetime
does make use of ReactDOM for some of its inner components。
第三方组件的建议解决方案是使用jest
自行模拟它们如果使用jest,解决方法很简单。只是嘲笑导致问题的第三方组件。
例如:
jest.mock('third-party-button', () => 'ThirdPartyButton');
将它放在测试文件的顶部。
现在任何第三方按钮的导入(用你的组件替换它)都将成为一个字符串(例如ThirdPartyButton),因此组件将成为快照中的“叶子”,就像div一样。当然,这实际上不会测试它,但仅测试自己的代码是有意义的。
答案 1 :(得分:0)
我使用酶的装载来解决它。
测试代码
import React from 'react';
import ReactTestRenderer from 'react-test-renderer';
import { shallow, mount } from 'enzyme'; // helps to handle refs
import thunk from 'redux-thunk';
import TestComponent from 'pathtocomponent';
describe('<TestComponent />', () => {
it('should render a action model when order is approved', () => {
const component = mount(
<TestComponent
message="sample message" level="success" title="title sample"
/>
);
component.instance().componentDidMount();
expect(component).toBeDefined();
});
});
具有Ref的组件:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactNotificationSystem from 'react-notification-system';
export default class TestComponent extends Component {
constructor(props) {
super(props);
this.addNotification = this.addNotification.bind(this);
this.notificationSystem = null;
}
componentDidMount() {
this.notificationSystem = this.refs.notificationSystem;
this.addNotification();
}
addNotification() {
let that = this;
this.notificationSystem.addNotification({
message: that.props.message,
level: that.props.level,
position: 'tc',
autoDismiss: 4,
title: that.props.title,
});
}
render() {
return (<div>
<TestComponent ref="notificationSystem" />
</div>);
}
}