expect(jest.fn())[。not] .toHaveBeenCalled()错误

时间:2018-05-10 08:39:10

标签: reactjs jestjs enzyme

我正在使用Enzyme / Jest为我的组件上的函数编写测试,该测试通过onClick of a材质的菜单图标触发。该函数作为props传递给组件。在编写测试时,它给出了模拟点击的错误。

import React from 'react';
    import scssstyles from './ToggleSideNavComponent.scss';
    class ToggleSideNavComponent extends React.Component {
      render() {
        return (
            <a
              id="toggle_sidebar_btn"
              className={scssstyles.menuIcon}
              onClick={this.props.handleSideNavToggle}
              >
              <i id="menu" className="material-icons menu-icon" style={{fontSize:30}}>menu</i>
            </a>
        );
      }
    }


    module.exports = ToggleSideNavComponent;

TEST

import expect from 'expect';
import React from 'react';
import {mount, shallow} from 'enzyme';
import ToggleSideNavComponent from  './ToggleSideNavComponent';
import sinon from 'sinon';

function setup() {
    const props = {
        handleSideNavToggle: sinon.spy()

    };

    return {
        props: props,
        wrapper: shallow(<ToggleSideNavComponent {...props} />) 
    };
}

describe('ToggleSideNavComponent', () => {
    it('should have menu icon', () => {
        const component = setup();
        expect(component.wrapper.find('a #menu').length).toBe(1);

        component.wrapper.find('#toggle_sidebar_btn #menu').simulate('click');
        expect(component.props.handleSideNavToggle).toHaveBeenCalled();
    });
});

错误:

ToggleSideNavComponent › should have menu icon

    expect(jest.fn())[.not].toHaveBeenCalled()

    jest.fn() value must be a mock function or spy.
    Received:
      function: [Function proxy]

      at Object.<anonymous> (src/components/app/Header/NavLeftList/ToggleSideNavComponent/ToggleSideNavComponent.spec.js:25:94)
          at new Promise (<anonymous>)
          at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:188:7)

2 个答案:

答案 0 :(得分:0)

如果你正在使用Jest,你应该使用Jest的间谍,而不是Sinon。

Counter({3: 717, 1: 101, 2: 92, 4: 90})  # 3 being taken far more often - about 8:1:1:1 if
                                         # you close both eyes and squint really hard ;)

答案 1 :(得分:0)

我已经尝试过您的代码,但是使用shallow renderingfull DOM rendering更改为mount,并且一切正常:

import React from 'react';
import {shallow, mount} from 'enzyme';
import ToggleSideNavComponent from  './ToggleSideNavComponent';

function setup() {
    const props = {
            handleSideNavToggle: jest.fn()

    };

    return {
        props: props,
        wrapper: mount(<ToggleSideNavComponent {...props} />)
    };
}

describe('ToggleSideNavComponent', () => {
    it('should have menu icon', () => {
        const component = setup();
        expect(component.wrapper.find('a #menu').length).toBe(1);

        component.wrapper.find('#toggle_sidebar_btn #menu').simulate('click');
        expect(component.props.handleSideNavToggle).toHaveBeenCalled();

        component.wrapper.unmount(); // don't forget to use unmount() after mounting
    });
});

似乎在使用props时访问shallow rendering时遇到问题

如果您只想测试handleSideNavToggle函数的行为(只需对该函数进行单元测试),那么我建议您不要使用simulate来测试它,因为您不需要测试React的事件布线或浏览器的替代,您可以浅化呈现为组件ToggleSideNavComponent提供此prop函数的父组件,并使用适当的参数调用该方法并声明结果,例如:

describe('ToggleSideNavComponentParent', () => {
    it('test parent component function', () => {
        const wrapper = shallow(<ToggleSideNavComponentParent/>);
        const instance = wrapper.instance();
        let e = prepareSuitableEventObject();
        instance.handleSideNavToggle(e);

        // do your assertions here
    });
});

function prepareSuitableEventObject() {
    // construct an object and return it
}