Reputation: 1492
I have this React functional UI only component, which has two props passed in, the second being a function that is passed from its parent component. The onClick calls 'delegates' to a function in the parent container component, this parent method is then responsible for dispatching to a redux store.
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 test spec is, which uses Jasmine
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 has been rendered ', () => {
expect(wrapper.find('div').first()).not.toBe(null);
});
it(' div displays the correct bot text ', () => {
expect(wrapper.find('div').first().text()).toEqual(expectedDivText)
});
it(' div click event fired ', () => {
wrapper.simulate('click');
expect(wrapper.state('onClick')).toBe(true);
});
});
This last assertion fails with
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:26303:25)
at Object.<anonymous> (webpack:///app/react/components/bots/_tests/botShowUI.spec.js:25:23 <- tests.webpack.js:25415:25)
wrapper.simulate('click');
works, but the next line fails
What is the correct way to assert that the click was fired ?
Do I have to drop into wrapper's props/children instead of using state ?
I'm not trying to test the parent container in any way, the two are isolated. This test is only concerned with this UI component.
Upvotes: 0
Views: 493
Reputation: 1492
Based on Abhishek's answer here's my solution for Jasmine
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();
});
Hope this helps anyone.
Upvotes: 0
Reputation: 2977
First thing is that onClick isn't on state, but on props, so you will have to access it by doing wrapper.props('onClick')
.
Secondly, to test whether onClick has been handled or not is to use a spy, rather than an empty function. If you do not want to use spy, you can still do that, but not the way you have done. If you are interested, I can post some pseudo-code for that too. But coming back to using spies, you can use a spy as the onClick prop. Below is the code for that. I have hand-written it, so please check for any syntax error, but you should get the idea on what needs to be done.
it('should call the onClick handler on click', () => {
const onClickFunction = sinon.spy()
wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction} />)
wrapper.simulate('click');
expect(onClickFunction).toHaveBeenCalled();
})
Upvotes: 1