Ошибка: этот метод предназначен только для запуска на одном узле. 0 найдено вместо этого

Я тестирую функцию привязки клавиш в компоненте. Компонент довольно простой, прослушиватель событий для keyup и запускает сокращенное действие, которое скроет компонент.

Я очистил свой код здесь только от релевантной информации. Я могу пройти тест, если просто использую диспетчер магазина для выполнения вызова действия, но это, конечно, противоречит цели этого теста. Я использую Enzyme для имитации события keyup с соответствующими данными события (код клавиши для esc), но сталкиваюсь с ошибкой ниже.

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.<anonymous> (/Users/[name]/repos/[repoName]/webpack/test.config.js:162808:55 <- webpack:///src/test/components/MyComponent-test.js:39:40)

person Sam Sedighian    schedule 23.05.2016    source источник


Ответы (3)


Эта ошибка возникает, когда, как говорится, вы запускаете ее с любым количеством узлов, отличным от 1.

Подобно jQuery, ваш вызов find вернет некоторое количество узлов (на самом деле это единственная оболочка, которая знает, сколько узлов нашел ваш селектор find). И вы не можете вызывать simulate против 0 узлов! Или несколько.

Тогда решение состоит в том, чтобы выяснить, почему ваш селектор (styles.container в wrapper.find(styles.container)) возвращает 0 узлов, и убедиться, что он возвращает ровно 1, и тогда simulate будет работать так, как вы ожидаете.

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

Метод Enzyme debug действительно полезен здесь. Вы можете сделать console.log(container.debug()), а также console.log(container.html()), чтобы убедиться, что ваш компонент отображается так, как ожидалось во время теста.

person Tyler Collier    schedule 23.05.2016

Вы не найдете ни одного узла, потому что элемент, к которому вы пытаетесь добраться, находится на другом уровне. Выберите конкретный элемент по классу, id.. и попробуйте это

wrapper.find('LoginForm')
  .dive()
  .find('.CLASS_NAME_OF_ELEMENT')
  .simulate('click');
person Zenit    schedule 08.06.2020

Если у вас есть более одного HTML-элемента, например

 <button className = "age_up" onClick = {() => dispatch(onAgeUpAction())}> 
        Age UP 
        </button> 
        <button className = "age_down" onClick = {() => dispatch(onAgeDownAction())}>
             Age Down 
       </button> 
        <button type = "button"onClick = {handleClick}> 
        Fetch Post 
        </button> 

и вызывают его общим запросом, например

wrapper.find('button').simulate('click');

он вернет вам все три узла. Называйте его уникальными идентификаторами или именами классов.

person Ignatius Andrew    schedule 19.04.2020