Skip to content

Commit

Permalink
jest: Mock react-native ourselves.
Browse files Browse the repository at this point in the history
The immediate need is to set up a way to mock the new `ZLPConstants`
in `NativeModules`, which we'll do in an upcoming commit.

Doing this, as recommended by React Native [1], also means we're
better prepared for the React Native v0.61 upgrade (#3781), in which
Haste is removed [2]. A consequence of that removal, it seems, is
that mocks like this one, which we have now:

```
jest.mock('Linking', () => { ... }`
```

, won't work. Several people have handled this by changing 'Linking'
to something like 'react-native/Libraries/Linking/Linking', but this
is brittle because it couples our tests with the current directory
structure in 'react-native'. Better to do it this way.

We considered following the advice of others at that issue,
including a blog post [3] responding to the official suggestion with
an alternative. But we didn't reproduce the problems the post's
author mentioned, and we've so far been able to explain the hiccups
we've seen.

[1] facebook/react-native#26579 (comment)
[2] facebook/react-native#26579 (comment)
[3] facebook/react-native#26579 (comment)
  • Loading branch information
chrisbobbe committed Jul 7, 2020
1 parent cd16154 commit e956f99
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions jest/jestSetup.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,46 @@
import mockAsyncStorage from '@react-native-community/async-storage/jest/async-storage-mock';
import * as ReactNative from 'react-native';

// Following upstream advice [1], mock `react-native` ourselves.
//
// Helpful in particular for adding to NativeModules, to simulate
// modules being available after the bridge initializes.
//
// The 'react-native' we import here is already mocked to a great
// extent by `node_modules/react-native-jest/setup.js`, thanks to our
// having declared `preset: 'react-native'` in our Jest config.
//
// For how we fall back on these already-mocked properties:
//
// Following the suggested implementation, we don't do something like
// an object spread, but instead set the returned object's prototype
// to be ReactNative. They don't explain why, but at least one reason
// seems to be to avoid triggering deprecation warnings on accessing,
// e.g., ReactNative.CameraRoll, which would would be done during a
// spread as each property is enumerated.
//
// [1] https://github.com/facebook/react-native/issues/26579#issuecomment-535244001

jest.mock('react-native', () =>
// Extend ReactNative
Object.setPrototypeOf(
{
// We don't mock anything in these two, but
// `react-native-vector-icons` uses an odd indirection: they
// have a `lib/react-native.js` file with just the following:
//
// `export * from 'react-native';`
//
// This seems to mean that the ReactNative prototype (which
// we're setting to be the prototype of the object created by
// this literal) is ignored. So, put these directly in the
// object literal.
Platform: ReactNative.Platform,
StyleSheet: ReactNative.StyleSheet,
},
ReactNative,
),
);

jest.mock('@react-native-community/async-storage', () => mockAsyncStorage);

Expand Down

0 comments on commit e956f99

Please sign in to comment.