Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing in React with TypeScript, Jest and Enzyme: Cannot invoke an object which is possibly 'undefined'

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

In my last question Brian explained to me how to correctly test the press of a button. My problem is that the buttons onPress prop may be undefined. Let me show you the code:

export class HomeScreen extends Component<Props, object> {
  // ... navigationOptions and stuff

  handlePress = () => {
    this.props.navigation.navigate("QuestionsScreen");
  };

  render() {
    return (
      <View style={styles.container}>
        <Button
          raised={true}
          title={strings.painButtonTitle}
          buttonStyle={styles.painButton}
          titleStyle={styles.title}
          onPress={this.handlePress}
        />
      </View>
    );
  }
}

And here is the test I write for testing the interaction with the button:

describe("interaction", () => {
  const props = createTestProps({});
  const wrapper = shallow<HomeScreen>(<HomeScreen {...props} />);

  describe("clicking the Pain Button", () => {
    it("should navigate to the 'QuestionsScreen'", () => {
      wrapper.instance().handlePress = jest.fn();
      wrapper.find(Button).prop("onPress")({} as any);

      expect(wrapper.instance().handlePress).toHaveBeenCalledTimes(1);
    });
  });
});

The problem is here that my test won't run, because the linter says that onPress may be undefined:

Cannot invoke an object which is possibly 'undefined'.

How can I fix this?

I tried wrapping my code in an if statement like this:

if (typeof wrapper.find(Button).prop("onPress") !== undefined) {
  wrapper.find(Button).prop("onPress")({} as any);
}

But this also does not work.

like image 511
J. Hesters Avatar asked Oct 08 '18 07:10

J. Hesters


People also ask

Can you write Jest tests in TypeScript?

Via ts-jest ​ts-jest is a TypeScript preprocessor with source map support for Jest that lets you use Jest to test projects written in TypeScript. In order for Jest to transpile TypeScript with ts-jest , you may also need to create a configuration file.

Can I use Jest without Enzyme?

Jest can be used without Enzyme, and snapshots can be created and tested perfectly fine. But the Enzyme adds additional functionality to it. An enzyme can also be used without Jest, but we need any other test runner paired with it. Jest:- Jest as a test runner, assertion library, and mocking library.

Can you use Jest with React?

Jest is a JavaScript testing framework that allows developers to run tests on JavaScript and TypeScript code and can be easily integrated with React JS.


1 Answers

You can either use the non-null assertion operator like this:

wrapper.find(Button).prop("onPress")!({} as any);

...or assign the handler to a variable and call it behind a guard like this:

const handler = wrapper.find(Button).prop("onPress");
if (handler) {
  handler({} as any);
}
like image 174
Brian Adams Avatar answered Oct 26 '22 22:10

Brian Adams