Hi.
Here is a controlled form input, with a button calling some external (friendAdd) action with the current state.
const enhance = compose(
withState('newFriendName', 'setNewFriendName', ''),
withHandlers({
handleChangeName: ({ setNewFriendName }) => name => {
setNewFriendName(name);
},
handleAddButton: ({ friendAdd, newFriendName }) => () => {
friendAdd(newFriendName); // Redux action
},
}),
);
function FriendList({ newFriendName, handleChangeName, handleAddButton }) {
return (
<Container>
<Input
value={newFriendName}
onChangeText={handleChangeName}
/>
<Button onPress={handleAddButton} />
</Container>
);
}
export default enhance(FriendList);
This component (actually the non-stripped version) does work fine. The issue is when testing.
With enzyme I wanted to test both the input and the button handler.
I set the text into the Input, I press the Button, then I test the newFriendName state/prop and also test that the external friendAdd function is called with the right value. Like this:
describe('when entering a name in the input and pressing add', () => {
const props = { friendAdd: jest.fn() };
const component = shallow(<FriendAdd {...props} />);
const input = component.dive().find(Input);
const button = component.dive().find(Button);
beforeAll(() => {
input.props().onChangeText('Someone');
component.update();
button.simulate('press');
});
it('add the new friend', () => {
expect(component.props().newFriendName).toEqual('Someone');
expect(props.friendAdd).toBeCalledWith('Someone');
});
});
The first expect passes
So the state is getting updated.
but the second doesn't pass: the function is called, but with an empty string (the default).
Somehow the handleAddButton handler is not getting the updated prop.
I thought that component.update() would help, but it doesn't.
Any idea?
Anyway thanks for your time.
Idea from the top of my head, not sure if that'll work : Did you try with full rendering ?
I see you're using Enzyme#shallow. Since shallow rendering only render components one level deep, the issue could come from there. Try to replace it with Enzyme#mount.
Again, I didnt test any of this :)
Sorry I should have mentioned it's React-Native code, so afaik mount() is not an option.