问题
I'm building a React Native app with TypeScript. I'm doing my component tests using Jest and Enzyme. I'm also using React Navigation
I'm struggling to write the unit test for clicking my button.
Here is the component's code (just the render function):
render() {
const { navigation } = this.props;
return (
<View style={styles.container}>
<Button
raised
title={strings.painButtonTitle}
buttonStyle={styles.painButton}
titleStyle={styles.title}
onPress={() => navigation.navigate("QuestionsScreen")}
/>
</View>
);
}
Now here is the unit test.
describe("interaction", () => {
let wrapper: ShallowWrapper;
let props: Props;
beforeEach(() => {
props = createTestProps({});
wrapper = shallow(<HomeScreen {...props} />);
});
describe("clicking the Pain Button", () => {
it("should navigate to the 'QuestionsScreen'", () => {
wrapper.find("Button").simulate("click");
expect(props.navigation.navigate).toHaveBeenCalledTimes(1);
});
});
});
This fails and claims the navigation.navigate
function - which is mocked using jest.fn() - is never called.
I assume it has something to do with providing an error function to the button. The problem is, I can't not do that, since I need to call with the argument "QuestionsScreen"
. So I can't do something like onPress={this.navigation.navigate)
and then miraculously call "QuestionsScreen"
, can I?
How can I get this test to pass?
回答1:
The "Common Gotchas" section for simulate says that "even though the name would imply this simulates an actual event, .simulate() will in fact target the component's prop based on the event you give it. For example, .simulate('click') will actually get the onClick prop and call it."
That behavior can be seen in the Enzyme
source code here and here.
So the line wrapper.find("Button").simulate("click");
ends up trying to call the onClick
prop of the Button
which doesn't exist so it essentially does nothing.
This post from an Airbnb dev recommends invoking props directly and avoiding simulate
.
Here is a modified test that invokes the onPress
prop directly:
it("should navigate to the 'QuestionsScreen'", () => {
wrapper.find(Button).props().onPress({} as any);
expect(props.navigation.navigate).toHaveBeenCalledTimes(1); // SUCCESS
});
回答2:
I had a similar question with you. I tried simulate("click")
but failed because there's no onClick
property of the component.
My way was to change the test case to wrapper.find("form").simulate("submit")
because my navigation function was defined in the submit property of the form.
来源:https://stackoverflow.com/questions/52692824/how-to-test-a-button-click-in-react-with-typescript-jest-and-enzyme