2016-05-23 4 views
7

Ich teste eine Keybinding-Funktion in einer Komponente. Die Komponente ist ziemlich einfach, Ereignis-Listener für die 'keyup' und startet eine Redux-Aktion, die die Komponente verstecken wird. Ich habe meinen Code hier nur um relevante Informationen bereinigt. Ich bin in der Lage, den Test bestanden zu haben, wenn ich nur den Geschäftsversand nutze, um den Aktionsaufruf zu machen, aber das wird natürlich den Zweck dieses Tests vereiteln. Ich benutze Enzyme, um das Ereignis 'keyup' mit den entsprechenden Ereignisdaten (Schlüsselcode für 'esc') zu simulieren, aber ich stoße auf den Fehler unten.Fehler: Diese Methode soll nur auf einzelnen Knoten ausgeführt werden. 0 gefunden statt

MyComponent.js

import React, {Component, PropTypes} from 'react'; 
import styles from './LoginForm.scss'; 
import {hideComponent} from '../../actions'; 
import {connect} from 'react-redux'; 

class MyComponent extends Component { 
    static propTypes = { 
     // props 
    }; 

    componentDidMount() { 
    window.addEventListener('keyup', this.keybindingClose); 
    } 

    componentWillUnmount() { 
    window.removeEventListener('keyup', this.keybindingClose); 
    } 

    keybindingClose = (e) => { 
    if (e.keyCode === 27) { 
     this.toggleView(); 
    } 
    }; 

    toggleView =() => { 
    this.props.dispatch(hideComponent()); 
    }; 

    render() { 
    return (
     <div className={styles.container}> 
     // render code 
     </div> 
    ); 
    } 
} 

export default connect(state => ({ 
    // code 
}))(MyComponent); 

MyComponent-test.js

import React from 'react'; 
import chai, {expect} from 'chai'; 
import chaiEnzyme from 'chai-enzyme'; 
import configureStore from 'redux-mock-store'; 
import {mount} from 'enzyme'; 
import {Provider} from 'react-redux'; 
import thunk from 'redux-thunk'; 
import {MyComponent} from '../../common/components'; 
import styles from '../../common/components/MyComponent/MyComponent.scss'; 

const mockStore = configureStore([thunk]); 
let store; 
chai.use(chaiEnzyme()); 

describe.only('<MyComponent/>',() => { 
    beforeEach(() => { 
    store = mockStore({}); 
    }); 

    afterEach(() => { 
    store.clearActions(); 
    }); 

    it('when esc is pressed HIDE_COMPONENT action reducer is returned',() => { 
    const props = { 
     // required props for MyComponent 
    }; 
    const expectedAction = { 
     type: require('../../common/constants/action-types').HIDE_COMPONENT 
    }; 
    const wrapper = mount(
     <Provider store={store} key="provider"> 
     <LoginForm {...props}/> 
     </Provider> 
    ); 
    // the dispatch function below will make the test pass but of course it is not testing the keybinding as I wish to do so 
    // store.dispatch(require('../../common/actions').hideComponent()); 
    wrapper.find(styles.container).simulate('keyup', {keyCode: 27}); 
    expect(store.getActions()[0]).to.deep.equal(expectedAction); 
    }); 
}); 

Error: This method is only meant to be run on single node. 0 found instead.

at ReactWrapper.single (/Users/[name]/repos/[repoName]/webpack/test.config.js:5454:18 <- webpack:///~/enzyme/build/ReactWrapper.js:1099:0)

at ReactWrapper.simulate (/Users/[name]/repos/[repoName]/webpack/test.config.js:4886:15 <- webpack:///~/enzyme/build/ReactWrapper.js:531:0)

at Context. (/Users/[name]/repos/[repoName]/webpack/test.config.js:162808:55 <- webpack:///src/test/components/MyComponent-test.js:39:40)

Antwort

16

Dieser Fehler tritt auf, wenn, wie es heißt, können Sie es mit einer beliebigen Anzahl von anderen Knoten als 1.

laufen Ähnlich jQuery, Ihr find Aufruf wird eine bestimmte Anzahl von Knoten zurückgeben s (es ist wirklich ein einzelner Wrapper, der weiß, wie viele Knoten Ihr Selector gefunden hat). Und Sie können nicht simulate gegen 0 Knoten aufrufen! Oder mehrere.

Die Lösung ist dann, um herauszufinden, warum Ihre Wähler (die styles.container in wrapper.find(styles.container)) 0 Knoten zurückkehrt, und stellen Sie sicher, es gibt genau 1, und dann simulate funktionieren wie erwartet.

const container = wrapper.find(styles.container) 
expect(container.length).to.equal(1) 
container.simulate('keyup', {keyCode: 27}); 
expect(store.getActions()[0]).to.deep.equal(expectedAction); 

Enzyms debug Methode ist hier wirklich nützlich. Sie könnten console.log(container.debug()) oder auch console.log(container.html()) ausführen, um sicherzustellen, dass Ihre Komponente während des Tests wie erwartet dargestellt wird.