应该调用 React Enzyme Jest 错误 jest.fn()

Posted

技术标签:

【中文标题】应该调用 React Enzyme Jest 错误 jest.fn()【英文标题】:React Enzyme Jest error jest.fn() should be called 【发布时间】:2018-05-20 00:28:09 【问题描述】:

我的组件如下

import React from 'react';
import  connect  from 'react-redux';
import  Button  from 'react-bootstrap';

import UserActions from '../../../actions/sampleUserAction';
import UserForm from '../../../views/sample/userForm';
import UsersList from '../../../views/sample/usersList';

@connect(store => (
    users: store.sampleUserReducer.users,
))

export default class UserComponent extends React.Component 
    constructor(props) 
        super(props);

        this.state = 
            displayForm: false,
            user:  id: '', fName: '', lName: '' ,
            isCreationMode: true,
        ;

        this.addNewUser = this.addNewUser.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.submitForm = this.submitForm.bind(this);
        this.editUser = this.editUser.bind(this);
        this.deleteUser = this.deleteUser.bind(this);
    

    addNewUser() 
        this.setState(
            displayForm: !this.state.displayForm,
            isCreationMode: true,
            user:  id: '', fName: '', lName: '' ,
        );
    

    createUser(users) 
        users.push(
            id: users.length + 1,
            fName: this.state.user.fName,
            lName: this.state.user.lName,
        );
        return users;
    

    updateUser(users) 
        users.forEach((user) => 
            if (user.id === this.state.user.id) 
                user.fName = this.state.user.fName;
                user.lName = this.state.user.lName;
            
        );
        return users;
    

    submitForm(e) 
        e.preventDefault();
        let  users  = this.props;

        if (this.state.isCreationMode) 
            users = this.createUser(users);
         else if (!this.state.isCreationMode) 
            users = this.updateUser(users);
        
        this.addNewUser();
        this.props.dispatch(UserActions.listUsers(users));
    

    handleChange(e) 
        const  id  = this.state.user;
        let  fName, lName  = this.state.user;
        if (e.target.name === 'fName') 
            fName = e.target.value;
        

        if (e.target.name === 'lName') 
            lName = e.target.value;
        

        this.setState( user:  id, fName, lName  );
    

    editUser(e, id) 
        const  users  = this.props;
        let user = users.filter(obj => obj.id === id);
        user = user.length > 0 ? user[0] : null;
        if (user != null) 
            this.setState(
                displayForm: true,
                isCreationMode: false,
                user:  id: user.id, fName: user.fName, lName: user.lName ,
            );
        
    

    deleteUser(e, id) 
        let  users  = this.props;
        users = users.filter(user => user.id !== id);
        this.props.dispatch(UserActions.listUsers(users));
    

    render() 
        console.log(this.state.displayForm);
        return (
            <div className="container-fluid">
                <div className="well">
                    Sample Users App With Redux
                </div>
                <UserForm
                  displayForm=this.state.displayForm
                  isCreationMode=this.state.isCreationMode
                  submitForm=this.submitForm
                  handleChange=this.handleChange
                  user=this.state.user
                  addNewUser=this.addNewUser
                />
                <UsersList
                  users=this.props.users
                  editUser=this.editUser
                  deleteUser=this.deleteUser
                />
                <div className="clearfix">
                    <Button bsStyle="primary" onClick=this.addNewUser>Add User</Button>
                </div>
            </div>
        );
    

测试文件如下

import React from 'react';
import  createMockStore  from 'redux-test-utils';
import  shallowWithStore  from 'enzyme-redux';
import  Button  from 'react-bootstrap';

import UserComponent from '../../../../src/components/containers/sample/userComponent';
import UserForm from '../../../../src/views/sample/userForm';
import UsersList from '../../../../src/views/sample/usersList';


describe('UsersComponent', () => 
    let store;
    let container;
    const props = 
        submitForm: jest.fn(),
        addNewUser: jest.fn(),
    ;

    beforeEach(() => 
        const defaultState =  sampleUserReducer:  users: []  ;
        store = createMockStore(defaultState);
        container = shallowWithStore(<UserComponent />, store);
    );

    it('should work', () => 
        expect(true).toEqual(true);
    );

    it('container should have UserForm component', () => 
        expect(container.dive().find(UserForm)).toHaveLength(1);
    );

    it('container should have UsersList component', () => 
        expect(container.dive().find(UsersList)).toHaveLength(1);
    );

    it('should have add new user button', () => 
        expect(container.dive().find(Button)).toHaveLength(1);
        expect(container.dive().find(Button).dive().text()).toEqual('Add User');
    );

    it('On click add user button', () => 
        container.dive().find(Button).simulate('click');
        expect(props.addNewUser).toHaveBeenCalled();
    );
);

我正在使用 jest、enzyme、enzyme-redux。我是反应单元测试的新手。最后一个测试用例给出如下错误。 React 版本是 16.x。在最后一个测试用例中,我试图在单击按钮时调用模拟的 jest 函数。对于使用 react-bootstrap 内置按钮组件的按钮

期望(jest.fn()).toHaveBeenCalled() 预期的模拟函数已被调用。

【问题讨论】:

【参考方案1】:

另一种选择是使用 jest 的间谍来断言 addNewUser 被调用。

const spy = jest.spyOn(container.instance(), 'addNewUser');
container.dive().find(Button).simulate('click');
expect(spy).toBeCalled();

【讨论】:

【参考方案2】:

有时container.update() 不起作用,在这种情况下,请在状态更改后更新组件的单击后在测试中尝试container.instance().forceUpdate()

【讨论】:

【参考方案3】:

您可能需要添加container.update();,这会在单击等外部输入后强制重新渲染。

http://airbnb.io/enzyme/docs/api/ShallowWrapper/update.html

【讨论】:

以上是关于应该调用 React Enzyme Jest 错误 jest.fn()的主要内容,如果未能解决你的问题,请参考以下文章

React / Enzyme:运行 Jest / Enzyme 测试时出现 Invariant Violation 错误

如何测试 Redux 的 dispatch() 是不是已在 React Component (Jest + Enzyme) 中被调用

当模拟点击调用调用 promise 的函数时,使用 React 的 Jest 和 Enzyme 进行测试

React/Jest/Enzyme - 等待时间不够长

如何测试从 mapDispatchToProps 传递的函数(React/Redux/Enzyme/Jest)

使用 React Suspense 和 React.lazy 子组件进行 Jest/Enzyme 类组件测试