Enzyme: On Click event for Mounted Component does not trigger state change

Created on 8 Feb 2018  路  2Comments  路  Source: enzymejs/enzyme

Thanks for reporting an issue to us! We're glad you are using and invested in Enzyme.
Before submitting, please read over our commonly reported issues to prevent duplicates!

Current behavior

The following test case should test the state change for when a user clicks on a specific tab

Below is the following test case written:

    test("click on api root tab opens the ApiRootForm", () => {
        const store = createMockStore(loggedInWithData);
        let wrapper = mountWithStore(<TaxiiResourcesForm/>, store);
        let tabs = wrapper.find('#taxii-tab').find('Tabs');
        let apiRootTab = tabs.find('#api-roots').find('Tab');
        let embeddedButton = apiRootTab.find('button');
        console.log(apiRootTab.debug());
        embeddedButton.prop('onClick')();
        expect(tabs.props().value).toEqual('api-roots'); // FAILED
    });

Helper functions:

import { mount } from 'enzyme';
import PropTypes from 'prop-types';
import { createShallow } from 'material-ui/test-utils';

/*
Note that with mount, it will render the component and all its children
including material UI components which will require the theme context
to be available as props. this will be passed down as part of the context,
just like the store.
 */

export const shallowWithStore = (component, store) => {
    let shallow;
    shallow = createShallow()
    const context = {
        store,
    };
    return shallow(component, { context });
};


export const mountWithStore = (component, store) => {
    const context = {
        store,
    };

    const childContextTypes = {store: PropTypes.object}

    return mount(component, {context, childContextTypes});
};


Tested Component:

import React from 'react';
import {connect} from 'react-redux'
import '../../../styles/TaxiiResourcesForm.css';
import Paper from 'material-ui/Paper';
import {getDiscoveryObject} from '../../actions/taxiiResources/actions';
import PropTypes from 'prop-types';
import Tabs, { Tab } from 'material-ui/Tabs';
import ApiRootForm from './ApiRootForm/ApiRootForm';
import ServerForm from './ServerForm';
import AppConfig from '../../appConfig';
import Typography from 'material-ui/Typography';

class TaxiiResourcesForm extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            activeTab: 'server-config'
        };
    }

    componentDidMount() {
        this.props.getDiscoveryObject();
    }

    _getTaxiiForm() {
        return (
            <Paper>
                <Tabs value={this.state.activeTab} id={"taxii-tab"} onChange={(event, value) => this.setState({activeTab:value})}>
                    <Tab value="server-config" id={"server-config"} label="Server Configurations"/>
                    <Tab value="api-roots" id={"api-roots"} label="API Roots"/>
                </Tabs>
                {this.state.activeTab === 'server-config' &&
                <Typography component="div" style={{ padding: 8 * 3 }}><ServerForm/></Typography>}

                {this.state.activeTab === 'api-roots' &&
                <Typography component="div" style={{ padding: 8 * 3 }}><ApiRootForm/></Typography>}
            </Paper>
        )
    }

    render() {
        return (
            <div className="TaxiiResourcesForm">
                {this.props.taxiiResources.rootApiArray ? this._getTaxiiForm() : null}
            </div>
        );
    }

}


function mapStateToProps({taxiiResources}) {
    return {taxiiResources}
}

function mapDispatchToProps(dispatch) {
    return {
        getDiscoveryObject: function () {
            dispatch(getDiscoveryObject())
        }
    }
}

/**
 * @property {object} taxiiResources - The {@link taxiiResourcesReducer}
 * @property {object} getDiscoveryObject - The discoveryObject passed in from the {@link taxiiResourcesReducer}
 */
TaxiiResourcesForm.propTypes = {
    taxiiResources: PropTypes.object.isRequired,
    getDiscoveryObject: PropTypes.func.isRequired,
};


export default connect(mapStateToProps, mapDispatchToProps)(TaxiiResourcesForm)

Expected behavior

expect(tabs.props().value).toEqual('api-roots'); should pass

Your environment

OS X

API

  • [ ] shallow
  • [X] mount
  • [ ] render

Version

| library | version
| ---------------- | -------
| Enzyme | 3.2.0
| React | 16.0.0
| Material UI | 1.0.0-beta.30

Adapter

  • [X] enzyme-adapter-react-16
  • [ ] enzyme-adapter-react-15
  • [ ] enzyme-adapter-react-15.4
  • [ ] enzyme-adapter-react-14
  • [ ] enzyme-adapter-react-13
  • [ ] enzyme-adapter-react-helper
  • [ ] others ( )
question v3 expected difference

Most helpful comment

In enzyme 3, after any state change, you have to re-find from the root. Specifically, you can't use tabs in the assertion in the last line.

All 2 comments

In enzyme 3, after any state change, you have to re-find from the root. Specifically, you can't use tabs in the assertion in the last line.

Yeah, You might need to change like this.

    test("click on api root tab opens the ApiRootForm", () => {
        const store = createMockStore(loggedInWithData);
        let wrapper = mountWithStore(<TaxiiResourcesForm/>, store);
        let tabs = wrapper.find('#taxii-tab').find('Tabs');
        let apiRootTab = tabs.find('#api-roots').find('Tab');
        let embeddedButton = apiRootTab.find('button');
        console.log(apiRootTab.debug());
        embeddedButton.prop('onClick')();

        // in v3, you need to add the following lines.
        wrapper.update();
        tabs = wrapper.find('#taxii-tab').find('Tabs');

        expect(tabs.props().value).toEqual('api-roots'); // FAILED
    });
Was this page helpful?
0 / 5 - 0 ratings

Related issues

heikkimu picture heikkimu  路  3Comments

blainekasten picture blainekasten  路  3Comments

abe903 picture abe903  路  3Comments

potapovDim picture potapovDim  路  3Comments

amcmillan01 picture amcmillan01  路  3Comments