Enzyme: Testing a function (was clicked) when passed as a prop

Created on 26 Apr 2017  路  5Comments  路  Source: enzymejs/enzyme

Here's my function react component, two props passed in, the second is a function that is passed up from the parent container. So a click on the div is 'delegated' to the parent component.
I'm using Jasmine for my testing not sinon

import React, {Component} from 'react';
import PropTypes from 'prop-types';
const BotShowUI = ({ bot,  onClick  }) => {
    return(
        <div id={bot.id}  onClick={onClick}>
            {bot.id} : {bot.text}
        </div>
    )
}

BotShowUI.propTypes = {
   bot: PropTypes.object.isRequired,
   onClick: PropTypes.func.isRequired
};
export default BotShowUI;

My simple spec is failing

import React, {Component} from 'react';
import { mount } from 'enzyme';

import BotShowUI from '../botShowUI';

function onClickFunction(){};

describe('botShowUI', () =>  {
    const bot = {id: 1, isDone: false, text: 'bot 123'};
    const expectedDivText = '1 : bot 123';
    const wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction} />);
    it(' div click event fired ', () => {
        wrapper.simulate('click');
        expect(wrapper.state('onClick')).toBe(true);
    });
});

The fail message is

Chrome 57.0.2987 (Windows 10 0.0.0) botShowUI  div click event fired  FAILED
        TypeError: Cannot read property 'onClick' of null
            at ReactWrapper.state (webpack:///~/enzyme/build/ReactWrapper.js:825:24 <- tests.webpack.js:26308:25)
            at Object.<anonymous> (webpack:///app/react/components/bots/_tests/botShowUI.spec.js:30:23 <- tests.webpack.js:25420:25)

I can't seem to get the prop to 'register' if that's the correct word to use.

Most helpful comment

Here's the solution

it(' div click event fired ', () => {
    let onClickFunction_spy = jasmine.createSpy('onClickFunction');
    const wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction_spy} />); 
    wrapper.simulate('click');
    expect(onClickFunction_spy).toHaveBeenCalled();
});

All 5 comments

Here's the solution

it(' div click event fired ', () => {
    let onClickFunction_spy = jasmine.createSpy('onClickFunction');
    const wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction_spy} />); 
    wrapper.simulate('click');
    expect(onClickFunction_spy).toHaveBeenCalled();
});

@bikerboyroy can it be solved with shallow instead of mount?

@milkers the same question is legal for me, because I don't want any bunch of dependencies more than those already have, jest/enzyme/enzyme-adapter-react-16 etc.

Though it turns out to be quite simple task:

    const obj = shallow(
        <PagesSelector
            lang="en"
            defaultPerPage="100"
            perPageRows={[ 25, 50, 100, 200 ]}
            page="1"
            perPage={50}
            updatePerPage={(e) => {}}/>
    )
obj.find('select').simulate('change')

in this example updatePerPage is the function passed by props to the calling onChange event, like this:

          <select onChange={(event) => {updatePerPage(event)}}
          value={perPage} className={styles.gt_select}>
          {
            perPageRows.map((rows, index) => {
                return <option key={index}>{rows}</option>;
            })
          }
          </select>

I'd suggest avoiding simulate entirely, and invoke .prop('onClick')() directly.

This seems answered; happy to reopen if not.

Was this page helpful?
0 / 5 - 0 ratings