Test if function is called react and enzyme - reactjs

I am trying to test one of the methods in my react component. It is being called after a button click so I have the simulation in place with enzyme
it('clone should call handleCloneClick when clicked', () => {
const cloneButton = wrapper.find('#clone-btn');
cloneButton.simulate('click');
});
My component method is here:
_handleCloneClick(event) {
event.preventDefault();
event.stopPropagation();
this.props.handleClone(this.props.user.id);
}
The _handleCloneClick is being called when the user clicks on the button thats in the simulation, how can I go about testing that its been called successfully?

There are two options, either you should spy on _handleCloneClick of component's prototype, before you render the component:
export default class cloneButton extends Component {
constructor(...args) {
super(...args);
this. _handleCloneClick = this. _handleCloneClick.bind(this);
}
_handleCloneClick() {
event.preventDefault();
event.stopPropagation();
this.props.handleClone(this.props.user.id);
}
render() {
return (<button onClick={this. _handleCloneClick}>Clone</button>);
}
}
And in your test:
it('clone should call handleCloneClick when clicked', () => {
sinon.spy(cloneButton.prototype, '_handleCloneClick');
const wrapper = mount(<cloneButton/>);
wrapper.find('#clone-btn').simulate('click');
expect(spy).toHaveBeenCalled() //adept assertion to the tool you use
});
Or, you can try to set a spy after rendering the component and invoke wrapper.update() afterwards:
it('clone should call handleCloneClick when clicked', () => {
const wrapper = mount(<cloneButton/>);
sinon.spy(wrapper.instance(), "_handleCloneClick");
wrapper.update();
wrapper.find('#clone-btn').simulate('click');
expect(spy).toHaveBeenCalled() //adept assertion to the tool you use
});

Related

React-Jest Unit test an external module method that affects state

I am working on a React application using Jest.
I want to test an imported module component method (closemodal):
<Modal
visible={this.state.showModal}
closemodal={() => this.setState({ showModal: false })} // <= this one
type="slideInDown"
>
I tried in my unit test to spy Modal closemodal method like that:
import Modal from "react-animated-modal";
let spyOnCloseModal;
beforeEach(() => {
spyOnCloseModal = jest.spyOn(Modal, "closemodal");
wrapper = shallow(<App />);
});
But when UT running I get this error:
Cannot spy the closemodal property because it is not a function; undefined given instead
Try passing a mock function.
test("checks closemodel", () => {
const props = {
closemodal: jest.fn()
};
const wrapper = shallow(<Modal {...props} />);
// trigger your `closemodal` function here
expect(props.closemodal).toHaveBeenCalledTimes(1);
});

How to test or get value from state in react?

Hi could you please tell me How to test or get value from state in react ?
getting error
wrapper.instance(...).handleClickShowPassword is not a function
here is my code
https://codesandbox.io/s/l2lk4n794l
it("toggle showpassword value", () => {
wrapper.setState({ showPassword: false });
wrapper.instance().handleClickShowPassword();
expect(wrapper.state.showPassword).toEqual(true);
});
Since LoginContainer is an wrapped with an HOC, you either need to export the component without withStyles HOC or use dive on the wrapper to get the instance of the component. Also state is a function on component instance and hence you need to call it to access state
describe("<LoginContainer/>", () => {
let wrapper;
beforeEach(() => {
wrapper = shallow(<LoginContainer />);
});
it("toggle showpassword value", () => {
const comp = wrapper.dive();
comp.dive().setState({ showPassword: false });
comp.instance().handleClickShowPassword();
expect(comp.state("showPassword")).toEqual(true);
});
});
Working demo

Jest: How to test prop that is an anonymous function?

I have a component that loads another component, sending it an anonymous function as a prop:
export class Header extends Component {
constructor(props) {
super(props)
this.state = { activeTab: TAB_NAMES.NEEDS_REVIEW }
}
filterByNeedsReview() {
const { filterByNeedsReviewFn } = this.props
this.setState({ activeTab: TAB_NAMES.NEEDS_REVIEW })
filterByNeedsReviewFn()
}
...
render() {
return (
<Container>
...
...
<FilterTab
active={this.state.activeTab === TAB_NAMES.NEEDS_REVIEW}
name={TAB_NAMES.NEEDS_REVIEW}
count={40}
onClick={() => this.filterByNeedsReview()}
/>
...
...
</Container>
)
}
}
I have this failing test:
it('renders a filter tab with the right props for needs review', () => {
const filterByNeedsReviewFn = jest.fn()
expect(
shallowRender({ filterByNeedsReviewFn })
.find(FilterTab)
.findWhere(node =>
_.isMatch(node.props(), {
active: true,
name: 'Needs Review',
count: 40,
onClick: filterByNeedsReviewFn, //<-------------- THIS DOESN'T WORK
})
)
).toHaveLength(1)
})
How would I test that onClick is the right thing?
I believe you don't need to check how internal event handlers look like. You might be interested in different things: if triggering event handler changes component as you expect(.toMatchSnapshot() is much better here instead of testing structure manually with .toHaveLength) and if callback you've passed through props is called when it should to(.toHaveBeenCalled). What if component is changed some day not to just call .props.filterByNeedsReviewFn() but also do some stuff like calling anything else? should your test fail just because there is named method passed somewhere inside? I believe it is not.
So I see your test to be
it('renders a filter tab with expected props after clicking', () => {
const comp = shallowRender({});
comp.find(FilterTab).simulate('click');
expect(comp).toMatchSnapshot();
});
it('calls callback passed after clicking on filter tab', () => {
const filterByNeedsReviewFn = jest.fn()
const comp = shallowRender({ filterByNeedsReviewFn });
comp.find(FilterTab).simulate('click');
// let's ensure callback has been called without any unexpected arguments
expect(filterByNeedsReviewFn ).toHaveBeenCalledWith();
});
I don't think you actually needed this code but I wanted to illustrate how clear such approach could be. Your component have API: props callback it calls and render output. So we can skip testing internals without any pitfalls

How do I mock a react component property in jest which is instance of another class?

I want to test a react component which has instance of a service as a property. This service's method is called by a method in the component. I want to mock the service so its implementation is not my concern. Following is excerpts of my requirement:
// Component
export class SomeComponent extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
someService - new SomeService(arg1, arg2)
handleClick() {
// some transformations
this.someService.someMethod()
}
render() {
return <Button onClick={this.handleClick}>
</Button>
}
}
// test
describe.only('<SomeComponent/>', () => {
it.only('should call handleClick when button is clicked', () => {
const wrapper = shallow(<SomeComponent/>) // shallow render from enzyme
const handleClick = jest.fn()
const instance = wrapper.instance()
instance.handleClick = handleClick
wrapper.find(Button).simulate('click')
expect(handleClick).toHaveBeenCalledTimes(1)
})
})
But now I get the implementation details error of the services. How can I mock the service so that I can simply test the method of my Component?
If your project is a webpack project, then https://github.com/plasticine/inject-loader is very useful. You can simply swap any dependency with a mock in just a few lines of code.
describe('SomeComponent', () => {
let SomeComponent;
let SomeServiceSpy;
beforeEach(() => {
SomeServiceSpy= // {a mock/spy};
SomeComponent= require('inject-loader!./SomeComponent')({
'../services/SomeService': {SomeServiceSpy},
});
});
it('should ...', () => {
const wrapper = shallow(<SomeComponent/>)
wrapper.find(Button).simulate('click')
expect(SomeServiceSpy).toHaveBeenCalledTimes(1)
});
});
Note: make sure you don't import the module under test (SomeComponent) at the top of your file. The require call does that part.

How do I test that a function is called within a method using jest+enzyme+react+typescript?

Say I have this method in my react component
handleSubmit(){
if (this.state.fireRedirect === false){
this.setState({ fireRedirect: true }, () => { this.addEndpoint() });
}
}
How do I test that addEndpoint was called using Jest and Enzyme?
Use jest.spyOn
const spy = jest.spyOn(Component.prototype, "addEndPoint");
const wrapper = shallow(<Component/>);
expect(spy).not.toHaveBeenCalled();
wrapper.instance().handleSubmit();
expect(spy).toHaveBeenCalled();

Resources