Simulate is meant to be run on 1 node = 0 found - reactjs

Unable to make the following test pass :
Using React JS / enzyme and jest
I already asked a similar question and try to apply the same method, but its not going through. Any reason ?? Substitute shallow = mount ? or add a dive() ?
file.test.js -
// jest mock functions (mocks this.props.func)
const updateSelectedFormJSON = jest.fn();
const closeModal = jest.fn();
const onClick = jest.fn();
const onSaveClick = jest.fn();
// defining this.props
const baseProps = {
selectedFormJSON :{
FORM_COLUMN:[],
},
updateSelectedFormJSON,
closeModal,
onClick,
onSaveClick,
describe('SpecifyBodyModal Test', () => {
let wrapper;
let tree;
beforeEach(() => wrapper = mount(<SpecifyBodyModal {...baseProps} />));
it('should call closeModal functions on button click', () => {
baseProps.closeModal.mockClear();
wrapper.setProps({
updateSelectedFormJSON :null
});
wrapper.find('.add-custom-field-close').at(0).simulate('click')
expect(baseProps.closeModal).toHaveBeenCalled();
});
the 2nd test is not passing: error Method “simulate” is meant to be run on 1 node. 0 found instead.
it('should call onSaveClick functions on button click', () => {
baseProps.onSaveClick.mockClear();
wrapper.setProps({
closeModal :null
});
wrapper.find('.tran-button specify-body-continue').at(1).simulate('click')
expect(baseProps.onSaveClick).toHaveBeenCalled();
here is the render file js.
onSaveClick = () => {
let json = Object.assign({}, this.props.selectedFormJSON);
for(let i in json.FORM_COLUMN) {
json.FORM_COLUMN[i].IncludeInBody = this.state[json.FORM_COLUMN[i].Name];
}
this.props.updateSelectedFormJSON(json);
this.props.closeModal();
render() {
return (
<div className='specify-grid-modal'>
<div className='fullmodal'>
<div className='fullmodal_title'>Specify Body</div>
<div title="Close Window" className="add-custom-field-close" onClick={() => this.props.closeModal()}><FontAwesome name='xbutton' className='fa-times preview-close' /></div>
</div>
<button className='tran-button specify-body-continue' onClick={() => {this.onSaveClick()}} >
Continue
</button>
<div className='specify-body-wrapper'>
{this.renderColumns()}
</div>
</div>
)
}

The error means that there are no matches for className.add-custom-field-close selector.
className is prop name and shouldn't be included into the selector:
wrapper.find('.add-custom-field-close').at(0).simulate('click')

The selector of to find the element looks wrong. Its className.add-custom-field-close but should be .add-custom-field-close

Thanks for the help
it('should call onSaveClick functions on button click', () => {
baseProps.closeModal.mockClear();
wrapper.setProps({
updateSelectedFormJSON :null
});
wrapper.find('.add-custom-field-close').at(0).simulate('click')
expect(baseProps.closeModal).toHaveBeenCalled();
});

Related

(Jest/Enzyme/React) How to assert that throttled function inside change handler has been called?

I need to assert that SearchInputActions.onSearchActivated(value) is called when something is written in an input. It is a callback which is in change handler handleChange. I've been trying to create to mocks - one for handleChange and one for search but it did not work either. I am using jest and enzyme for tests.
const SearchInput = () => {
const search = throttle(event => {
const value = event.target.value;
SearchInputActions.onSearchActivated(value);
});
const handleChange = event => {
event.persist();
search(event);
};
return (
<div>
<SomeChildComponent />
<input type="text" onChange={handleChange} />
</div>
)
}
Test:
it('should dispatch search action', async () => {
const tree = mount(<SearchInput />);
const spySearch = jest.spyOn(SearchInputActions, 'onSearchActivated');
SearchInputActions.onSearchActivated.mockImplementation(() => {})
tree.find('input').simulate('change', {target: value: 'test'}});
expect(spySearch).toBeCalled();
}
I figured it out: Because the callback function was throttled (lodash throttle) I needed to add jest.useFakeTimers(); Final code looks like this:
jest.useFakeTimers();
it('should dispatch search action', async () => {
const tree = mount(<SearchInput />);
const spySearch = jest.spyOn(SearchInputActions, 'onSearchActivated');
SearchInputActions.onSearchActivated.mockImplementation(() => {})
tree.find('input').simulate('change', {target: value: 'test'}});
expect(spySearch).not.toBeCalled();
jest.runAllTimers();
expect(spySearch).toBeCalled();
SearchInputActions.onSearchActivated.mockRestore();
}

reactjs - Testing Checkbox leads to a function call

I'm trying to write a unit test for when a checkbox is checked, which would lead to a function being called. The React component is:
const changeExamBoards = (e, filterOptions) => {
if(e.target.checked && !(filterOptions.examBoards.includes(e.target.value))) {
setfilterOptions({ ...filterOptions, examBoards: [...filterOptions.examBoards, e.target.value] });
}
else {
setfilterOptions({ ...filterOptions, examBoards: [...filterOptions.examBoards.filter(item => item !== e.target.value)] });
}
};
<div className='option-container' onChange={e => changeExamBoards(e, filterOptions)}>
<div className='question-option-container'><input className='question-option' type="checkbox" name="AQA" value="AQA" /> AQA</div>
<div className='question-option-container'><input className='question-option' type="checkbox" name="Edexcel" value="Edexcel" /> Edexcel</div>
<div className='question-option-container'><input className='question-option' type="checkbox" name="OCR" value="OCR" /> OCR</div>
<div className='question-option-container'><input className='question-option' type="checkbox" name="WJEC" value="WJEC" /> WJEC</div>
</div>
The unit test I've been trying to run:
describe('QuestionFilter component', () => {
let store;
let wrapper;
let mockChangeExamBoards;
let mockRefreshPage;
let mockChangeDifficulty;
beforeEach(() => {
store = mockStore({
question: []
});
mockChangeExamBoards = jest.fn();
mockRefreshPage = jest.fn();
store.dispatch = jest.fn();
mockChangeDifficulty = jest.fn();
const mockProps = {
store,
refreshPage: mockRefreshPage,
changeExamBoards: mockChangeExamBoards,
changeDifficulty: mockChangeDifficulty
}
wrapper = mount(<QuestionFilter {...mockProps} />
)
});
it('expect changeExamBoards to be called', () => {
const eMock = { preventDefault: jest.fn(), target: 'fake target', checked: true };
expect(mockChangeExamBoards).not.toHaveBeenCalled();
wrapper.find('.question-option-container')
.at(0)
.simulate('change', eMock);
expect(mockChangeExamBoards).toHaveBeenCalled();
});
However no matter how I try I keep getting this error:
QuestionFilter component › expect change difficulty to be called
expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
I thought the simulate would call the mock function but nothing seems to actually call it?

How to verify method is not invoked on mock passed as prop

I am developing a React application with jest and TypeMoq.
I can't test the negative path of a decision tree when the mocked call is a method on the object which needs to be undefined. Is there a method on TypeMoq that can help me verify that the provided method is not called?
type TopicComponentProps = {
topic: Topic
history?: History<any>
}
export const TopicComponent = ({topic, history} : TopicComponentProps) => {
const { Id, Name } = topic;
const filterTopic = () => {
if (history) { // <-- this is my problem
history.push(`/topic/overview/${Id}`);
}
}
return(
<Fragment>
<span
style={topicStyle}
onClick={() => filterTopic()}
className="topic">
{Name}
</span>
</Fragment>
)
}
The positive test case looks like this:
it('should trigger the navigation when clicked', () => {
const mockHistory = Mock.ofType<History<any>>();
const wrapper = mount(
<TopicComponent topic={testTopic} history={mockHistory.object} />
);
wrapper.simulate('click');
mockHistory.verify(x => x.push(It.isAnyString()), Times.once());
});
How do I setup the mock object, so i can test that no navigation happens when no history is provided?
it('should not trigger the navigation when history is undefined', () => {
let mockHistory = Mock.ofType<History<any>>();
???
const wrapper = mount(
<TopicComponent topic={testTopic} history={???} />
);
wrapper.simulate('click');
mockHistory.verify(x => x.push(It.isAnyString()), Times.never());
});

Method “simulate” is meant to be run on 1 node. 0 found instead. - Jest/Enzyme

I am trying to test the onClick but they are not being called using props:
here is part of the file.js
handleSystemClick = () => {
// var message = All unsaved changes will be lost.`
confirmAlert({
title: 'Confirm Navigation',
message: ' All unsaved changes will be lost.',
childrenElement: () => <div></div>,
confirmLabel: 'Confirm',
cancelLabel: 'Cancel',
onConfirm: () => {this.setState({ toSystemEntitlments: true})},
onCancel: () => {},
})
}
handleCancelClick = () => {
window.history.back();
}
here is render method of file.js
render()
return(
<div className='add-edit-button' id= 'test1' onClick={() => {this.handleSystemClick()}}>System</div>
<div className='add-edit-button' onClick={() => {this.handleCancelClick()}}>Cancel</div>
<div className='add-edit-button' onClick={() => {this.handleSave()}}>Save</div>
</div>
I have seen some examples here on stackoverflow and I tried to apply the following:
// jest mock functions (mocks this.props.func)
// defining this.props
const baseProps = {
describe(' FunctionalEntitlement Test', () => {
let wrapper;
let tree;
beforeEach(() => wrapper = shallow(<BrowserRouter><Component {...baseProps} /></BrowserRouter>));
it("should call handlesave function on button click", () => {
// Reset info from possible previous calls of these mock functions:
baseProps.handleSave.mockClear();
wrapper.setProps({
});
wrapper.setState({ getINITIAL_STATE:""
});
wrapper.find('.add-edit-button').at(0).simulate("click");
expect(baseProps.handleSave).toHaveBeenCalled();
expect(toJson(wrapper)).toMatchSnapshot();
});
Also How could I apply the same method for the first 2 clicks based on file.js
Thank you for the help
If you want to use shallow there is a way to get the shallow wrapper of one of the children using the dive method. If you have to wrap your components with BrowserRouter frequently on the test, maybe it's worth it to have a helper method for this like:
function shallowWithBrowserRouter(component) {
return shallow(<BrowserRouter>{component}</BrowserRouter>).childAt(0).dive();
}
Able to work something out but how could I improve the following answer.
Switched shallow to Mount in order to render children components
it("should call button click 3 times", () => {
// Reset info from possible previous calls of these mock functions:
wrapper.setProps({
});
wrapper.setState({
});
wrapper.find('.add-edit-button').at(0).simulate("click");
wrapper.find('.add-edit-button').at(1).simulate("click");
wrapper.find('.add-edit-button').at(2).simulate("click");
expect(toJson(wrapper)).toMatchSnapshot();
});

|ReactNative|-Conditional rendering ?: with Jest && Enzyme

Good afternoon,
I have a component file structured like that globally :
class Component ...
render(){
const {array} = this.props
{!array.includes(value) ?
(<View ...props
id="myComponent"/>
....
</View>) :
(<View ...props
id="myOtherComponent"/>
....
</View>)
}
}
And in my test file, i'm doing the stuff like that :
describe('Testing Component', () => {
test('conditional rendering', () => {
const wrapper = shallow(<Component array={[value]}/>);
expect(wrapper.find(n => n.prop('id') === "myOtherComponent").exists(true))
});
});
But even if I modify the props sent for the array, it always returned me true... What's the keyword to check that the nested component is actually verified and rendered...
I think the error is in your expect argument.
I would use the findWhere function instead of find;
The exists method should not receive a parameter in this
case, as it only receives Enzyme's Selectors and not booleans (you can read more about it here);
Add a toBeTruthy call to the expect line.
Here's a similar situation to yours that we have a test for and it works just fine:
it('tests name', () => {
const mockComponent = shallow(<Component {...props} />);
const textNode = mockComponent.findWhere(n => n.text() === props.name);
expect(textNode.exists()).toBeTruthy();
});
So your test would end up looking like this:
describe('Testing Component', () => {
test('conditional rendering', () => {
const wrapper = shallow(<Component array={[value]}/>);
const node = wrapper.findWhere(n => n.prop('id') === 'myOtherComponent');
expect(node.exists()).toBeTruthy();
});
});

Resources