错误:此方法仅适用于在单个节点上运行。 0找到

时间:2016-05-23 02:44:27

标签: reactjs mocha redux enzyme

我正在测试组件中的键绑定功能。该组件非常简单,是keyup的事件监听器,并触发 redux action ,它将隐藏组件。

我已将此处的代码清理为仅提供相关信息。如果我只是使用商店调度来进行动作调用,我就可以通过测试,但这当然会破坏这个测试的目的。我使用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);
  });
});
  

错误:此方法仅适用于在单个节点上运行。 0找到了。

     

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

     

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

     

在Context。 (/Users/[name]/repos/[repoName]/webpack/test.config.js:162808:55&lt; - webpack:///src/test/components/MyComponent-test.js:39:40)< / p>

4 个答案:

答案 0 :(得分:30)

正如所说的那样,当你使用除1以外的任意数量的节点运行它时,就会发生这种错误。

与jQuery类似,您的find调用将返回一定数量的节点(实际上它是一个知道您的find选择器找到了多少节点的包装器)。并且您无法针对0个节点调用simulate!或多个。

然后解决方案是弄清楚为什么你的选择器(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())以确保您的组件在测试期间按预期呈现。

答案 1 :(得分:4)

您找不到任何节点,因为您尝试到达的元素位于另一个级别。通过类id ..选择一个特定的元素,然后尝试

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jun  8 13:25:20 2020

@author: Pietro
"""
import sys 
from PyQt5 import QtWidgets 

class secondwindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(secondwindow,self).__init__()
        self.setWindowTitle("Second Window")
        self.hide()

答案 2 :(得分:0)

大家好,我用的是 1-先获取容器 2-得到按钮 3- 执行道具 onClick

 it('should Click on edit row', () => {
  const containerButton =  wrapper.find('.editCell')
  const editButton = containerButton.find('.buttonAlignRight')  
  editButton.props().onClick() 
  expect(wrapper.find('input')).toBeVisible()
})

答案 3 :(得分:-1)

如果您有多个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');

它将为您返回所有三个节点。 所以用唯一的ID或类名来称呼它。