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.
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.
Most helpful comment
Here's the solution