Spy a method that has been called when onPress on an Alert - reactjs

I am trying to test a removeService method that gets called when onPress 'ing inside an Alert like this
Alert.alert(
[...],
onPress: () => removeService();
);
}
this is the test:
const spyAlert = jest.spyOn(Alert,
"alert");
const spyRemoveService = jest.fn();
const wrapper = shallow(
<Component removeService={spyRemoveService} />
);
wrapper
.find("RemoveServiceButton")
.props()
.handleRemoveService();
// Click onPress
spyAlert.mock.calls[0][2][1].onPress();
expect(spyRemoveService).toHaveBeenCalledTimes(1);
However, when I run the test I get TypeError: removeService is not a function
why?

Related

Jest on React, test a prop is called

I have a component with a props that is an action called changeReason()
And then, I have a function called when I press a button. The function is:
const handleNext = React.useCallback(() => {
if (!reason) {
changeReason({
code: defaultReason,
value: defaultReason
});
}
}
I want to test that changeReason() prop is called, I'm trying to do a test like this:
const changeReason = jest.fn();
const rendered = render(
<TransactionReason
changeReason={changeReason}
reason={null}
/>
);
// When some button is pressed...
const reasonNext = rendered.getByTestId('reasonButton');
// it must fire an event
fireEvent.press(reasonNext);
const FakeFun = jest.spyOn(rendered, 'changeReason');
expect(FakeFun).toHaveBeenCalled();
I'm getting:
Cannot spy the handleNext property because it is not a function; undefined given instead
How could I test that I'm calling that action?

Cant test copy from 'copy-to-clipboard' with sinon

I'm trying to test my component with Sinon.
It seems I can't simulate the click function which is in the TableMenu component.
TableMenu.jsx
import copy from 'copy-to-clipboard';
const TableMenu = ({onClick, onHide, rowId}) => (
<MenuPopover
onClick={onClick}
onHide={onHide}>
<MenuPopover.Item id={1} onClick={() => copy(rowId)} label='Copy'/>
</MenuPopover>
);
TableMenu.test.js
import copy from 'copy-to-clipboard';
jest.mock('copy-to-clipboard', () => sinon.spy());
it('check method onCopy called', () => {
const wrapper = shallow(<TableMenu {...props}/>);
wrapper.find(MenuPopover.Item).last().props().onClick()
expect(copy.calledOnce).to.eql(true);
});
I'm getting the below error:
Error: Not implemented: window.prompt
at module.exports (C:\adm\node_modules\jsdom\lib\jsdom\browser\not-implemented.js:9:17)
at Window.prompt (C:\adm\node_modules\jsdom\lib\jsdom\browser\Window.js:458:7)
at copy (C:\adm\node_modules\copy-to-clipboard\index.js:58:14)
at Object.onClick (C:\adm\src\TableMenu/TableMenu.jsx:19:43)
...
...
TypeError: reselectPrevious is not a function
at copy (node_modules\copy-to-clipboard\index.js:72:5)
at Object.onClick (src\TableMenu/TableMenu.jsx:19:43)
at Context.<anonymous> (src\TableMenu/TableMenu.test.js:62:62)
at process.topLevelDomainCallback (domain.js:121:23)
I guess this is being discussed in the github repo and the potential solution could be #106 (comment)
Or, just simply mock an implementation for window.prompt. e.g.
jest.spyOn(window, 'prompt').mockImplementation();

How to test child components props method in the parent component test

I'm writing a test for my parent class which contains a child component. The code coverage reports that I haven't covered test for child components props method. Below is my structure of my components
export const CreateSRFullScreenPanel: React.FC<Props> = ({
interPluginContext,
srType,
errorMessage,
}: Props) => {
const [disableButton, setDisableButton] = React.useState(false);
const [submitSR, setSubmitSR] = React.useState(false);
const returnToHomePage = (): void => {
getRouteClient()
.changeRoute(getActiveRegionBaseUrl(state.regionName));
};
const cancelOp = interPluginContext.isValid()
? CancelAction
: returnToHomePage;
...
<childSR disableButton={disableButton} onSubmitComplete={() =>
setSubmitSR(false)}/>
<Button
type={ButtonType.Submit}
buttonStyle={ButtonStyle.Primary}
onClick={cancelOp}
>
Cancel
</Button>
};
When I wrote a test like below I was getting undefined for method calls.
it("check props method gets called", () => {
const wrapper = mount(
<ParentSR {...props} />
);
console.log(wrapper.find(CreateSR).props().onSubmitComplete()); // undefined
console.log(wrapper.find(CreateSR).props().disableButton()); // true
});
Also, when I click on a cancel button cancelOp method gets called. How do I mock returnToHomePage method calls?

How to simulate a click on a Font Awesome Icon using Jest?

I'm testing through Jest and am trying to test the click on a Font Awesome Icon. I've tried different ways to find the 'node', but I get the error that "Method “simulate” is meant to be run on 1 node. 0 found instead." Any insight would be helpful.
The error I get when I try different inputs to component.find() is: Method “simulate” is meant to be run on 1 node. 0 found instead.
StringEditor
const clearInput = () => {
onRemove()
}
render (
...
<FontAwesomeIcon icon={['fal', 'times-circle']} className="clear-button"
onClick={clearInput} /> : null`
)
onRemove is a callback function.
it('should call clearInput thus onRemove', () =>{
const onRemove= jest.fn()
const component = mount(<StringEditor {...defaultProps} onRemove={onRemove} />)
component.find('<dont know what to put>').simulate('click')
expect(saveValueFn).toBeCalled()
})
Try this:
it('should call clearInput thus onRemove', () =>{
const onRemove= jest.fn()
const component = mount(<StringEditor {...defaultProps} onRemove={onRemove} />)
component.find({ className: "clear-button" }).simulate('click');
expect(clearInput).toHaveBeenCalled();
})
You can use the Object Property Selector: https://airbnb.io/enzyme/docs/api/selector.html#4-object-property-selector
Or a React Component Constructor: https://airbnb.io/enzyme/docs/api/selector.html#2-a-react-component-constructor

Function call inside useEffect not firing in jest test

I have a component that, on button click sends the updated value to parent via props.OnValChange. This is implemented in the useEffect hook.
If I console log the useEffect I can see it being called. But in my test when I do expect(prop.OnValChange).toHaveBeenCalledTimes(1); it says it was called 0 times.
Component:
const MyComp = ({OnValChange}) => {
const [ val, setVal ] = useState(0);
useEffect(() => {
console.log("before");
OnValChange(val);
console.log("after");
}, [val]);
return (
<button onClick={() => setVal(val + 1)}>Count</button>
)
}
Test:
it("Sends val to parent when button is clicked", () => {
const prop = {
OnValChange: jest.fn();
}
const control = mount(<MyComp {...prop} />);
expect(prop.OnValChange).toHaveBeenCalledTimes(0);
control.find(button).simulate("click");
expect(prop.OnValChange).toHaveBeenCalledTimes(1);
})
useEffect will always be called once when the component is initially mounted, and will be called a second time when you trigger a button click, so the correct test should be like this
it("Sends val to parent when button is clicked", () => {
const prop = {
OnValChange: jest.fn();
}
const control = mount(<MyComp {...prop} />);
expect(prop.OnValChange).toHaveBeenCalledTimes(1);
control.find(button).simulate("click");
expect(prop.OnValChange).toHaveBeenCalledTimes(2);
})
If you are always 0 times, I suspect that it is a problem with the version of enzyme-adapter-react-16. When I switch the version to 1.13.0, there will be the same problem as you, you can try enzyme -adapter-react-16 updated to the latest version.

Resources