2017-07-27 174 views
2

我使用笑话为了使用快照测试。ReactTestRenderer:不变的违规:getNodeFromInstance:无效的参数

我遇到了react-test-renderer中的一个bug,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> 
     ); 
    } 
} 

下面是测试spec文件

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) 

可有人请点我我在做什么错了,并且指导我解决这个问题。

回答

1

相关问题讨论here

如前所述这种情况如预期,因为

React test renderer is not coupled to React DOM. It can't "guess" which DOM APIs your component relies on. You need to mock the nodes yourself, as noted in 15.4.0 release notes. I hope this helps!

你可以看到你的包react-datetime does make use of ReactDOM for some of its inner components

第三方组件建议的解决方法是自行嘲笑他们开玩笑

The workaround is simple if you use jest. Just mock the third party component causing issues.

For example:

jest.mock('third-party-button',() => 'ThirdPartyButton');

Put this at the top of your test file.

Now any imports of third-party-button (replace this with your component) will become a string (e.g. ThirdPartyButton) so the component will become a “leaf” in the snapshot, like a div. Of course this won't actually test it, but it makes sense to only test your own code.

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(); 
    }); 

}); 

组件与参考:

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>); 
    } 
}