1

I have set up redux-persist with async-storage but my jest tests are failing with an error that refers to async code. The error is cryptic and I can't find what is causing it.

> app@0.0.1 test /Desktop/app
> jest --detectOpenHandles

ts-jest[main] (WARN) Replace any occurrences of "ts-jest/dist/preprocessor.js" or  "<rootDir>/node_modules/ts-jest/preprocessor.js" in the 'transform' section of your Jest config with just "ts-jest".

ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.

      at Object.get BackHandler [as BackHandler] (node_modules/react-native/Libraries/react-native/react-native-implementation.js:222:12)
      at new NavigationContainer (node_modules/@react-navigation/native/dist/createAppContainer.js:190:35)
      at constructClassInstance (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2996:22)
      at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5896:9)
      at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6674:20)
      at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:10041:16)

  ●  Cannot log after tests are done. Did you forget to wait for something async in your test?
    Attempted to log "The above error occurred in the <NavigationContainer> component:
        in NavigationContainer (created by App)
        in App
        in PersistGate
        in Provider

    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://reactjs.org/docs/error-boundaries.html to learn more about error boundaries.".

      at CustomConsole.error (node_modules/@jest/console/build/CustomConsole.js:123:10)
      at logCapturedError (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7959:17)
      at logError (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7995:9)
      at update.callback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8912:9)
      at callCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7324:16)
      at commitUpdateEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7357:11)
      at commitUpdateQueue (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7347:7)
      at commitLifeCycles (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8231:15)
      at commitAllLifeCycles (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9531:11)
      at Object.invokeGuardedCallbackImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2057:14)

 PASS  __tests__/App-test.tsx
  ✓ renders correctly (11ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.118s, estimated 5s
Ran all test suites.
npm ERR! Test failed.  See above for more details.

I have tried both of the jest implementation provided by react-native-community.

https://github.com/react-native-community/async-storage/blob/master/docs/Jest-integration.md

And this SO answer but I can't figure it out.

How to test Async Storage with Jest?


/**
 * App-test.txt
 */

import 'react-native'
import renderer from 'react-test-renderer'
import React from 'react'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/es/integration/react'
import mockAsyncStorage from '@react-native-community/async-storage/jest/async-storage-mock';

import App from '../App'
// Note: test renderer must be required after react-native.

import configureStore from './../app/store'

const { store, persistor } = configureStore()


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


jest.mock('NativeModules', () => ({
  UIManager: {
    RCTView: () => ({
      directEventTypes: {}
    })
  },
  KeyboardObserver: {},
  RNGestureHandlerModule: {
    attachGestureHandler: jest.fn(),
    createGestureHandler: jest.fn(),
    dropGestureHandler: jest.fn(),
    updateGestureHandler: jest.fn(),
    State: {},
    Directions: {}
  }
}))

it('renders correctly', () => {
  renderer.create(
    <Provider store={store}>
      <PersistGate persistor={persistor}>
        <App />
      </PersistGate>
    </Provider>
  )
})

my jest config in package.json

"jest": {
    "setupFiles": ["./__mocks__/@react-native-community/async-storage.js"],
    "preset": "react-native",
    "transformIgnorePatterns": [
      "/node_modules/(?!native-base)/"
    ],
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ],
    "transform": {
      "^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
      "\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
    "testPathIgnorePatterns": [
      "\\.snap$",
      "<rootDir>/node_modules/"
    ],
    "cacheDirectory": ".jest/cache"
  },

async-storage.js

import mockAsyncStorage from '@react-native-community/async-storage/jest/async-storage-mock';

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

Max
  • 364
  • 1
  • 2
  • 10
BoKKeR
  • 125
  • 3
  • 14
  • rather than do that jest.mock line in async-storage.js, just replace it with `export default mockAsyncStorage;`. Also, you shouldn't _need_ to add the mocks inside of __mocks__ to the setupFiles array, and you should be able to also remove the mock line from the test file for App, since it should now always use the file in __mocks__ by default. – Justin Stanley Aug 08 '19 at 13:34

0 Answers0