Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock a class and namespace enums using jest?

react-native-google-signin defines the following:

export interface GoogleSigninButtonProps extends ViewProps {
  style?: StyleProp<ViewStyle>;
  size?: GoogleSigninButton.Size;
  color?: GoogleSigninButton.Color;
  disabled?: boolean;
  onPress?(): void;
}

export class GoogleSigninButton extends React.Component<GoogleSigninButtonProps> {
  constructor(props: GoogleSigninButtonProps);
}

export namespace GoogleSigninButton {
  enum Size {
    Standard,
    Wide,
    Icon,
  }

  enum Color {
    Light,
    Dark,
  }
}

and in my code I am using it as such:

<GoogleSigninButton
        style={{ width: 192, height: 48 }}
        size={GoogleSigninButton.Size.Wide}
        color={GoogleSigninButton.Color.Dark}
        onPress={this.authenticate}
        testID={'GoogleAuthenticationButton'}
      />

I have written my test to try an mock this as follows:

jest.mock('react-native-google-signin', () => ({
  GoogleSigninButton: {
    Size: {
      Standard: 0,
      Wide: 1,
      Icon: 2
    },
    Color: {
      Light: 0,
      Dark: 1
    }
  }
}))

However I get the following error:

Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

I have tried setting the GoogleSigninButton: 'GoogleSigninButton' and that will fix the expected return type but it will generate other errors such as Size and Color being undefined. If I keep it as is, then I get the error above.

How can I mock the above class so that it will return a string for GoogleSignInButton but also define the Size and Color properties so it doesn't throw a 'Cannot read property Size of undefined'?

like image 423
uioporqwerty Avatar asked Oct 25 '25 18:10

uioporqwerty


1 Answers

I have fixed it with the following modifications:

In my test:

jest.doMock('react-native-google-signin', () => () => {
  const GoogleSigninButton = () => {}
  GoogleSigninButton.Color = {
    Auto: 0,
    Light: 1,
    Dark: 2
  }
  GoogleSigninButton.Size = {
    Icon: 0,
    Standard: 1,
    Wide: 2
  }

  return GoogleSigninButton
})

I also created a react-native-modules.ts file with the following content:

import { NativeModules } from 'react-native'

NativeModules.RNGoogleSignin = {
  SIGN_IN_CANCELLED: '0',
  IN_PROGRESS: '1',
  PLAY_SERVICES_NOT_AVAILABLE: '2',
  SIGN_IN_REQUIRED: '3'
}

export { NativeModules }

And in jest.config.js I added the following property:

setupFiles: ['./tests/__mocks__/react-native-modules.ts'],

This is required because GoogleSignIn uses RNGoogleSignin from NativeModules and calls the properties redefined above (e.g. SIGN_IN_CANCELLED).

like image 175
uioporqwerty Avatar answered Oct 28 '25 07:10

uioporqwerty



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!