async-storage: SyntaxError: Unexpected token export using jest

Current behavior

/@react-native-community/async-storage/lib/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export default from './AsyncStorage';

 SyntaxError: Unexpected token export

    > 1 | import AsyncStorage  from "@react-native-community/async-storage"
        | ^
      2 | 
      3 | /**
      4 |  * Loads a string from storage.

Repro steps

import @react-native-community/async-storage and test with jest.

Environment

  • Async Storage version: 1.2.1
  • React-Native version: 0.57.7
  • Platform tested: iOS / Android
  • Jest version: 24.0.11
  • Logs/Error that are relevant: see above

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 9
  • Comments: 37 (11 by maintainers)

Most upvoted comments

Hey @loic-lopez

Async Storage is not being transformed by Jest, so in your jest.config.js or jest entry in package.json, add:

"transformIgnorePatterns": ["/node_modules/@react-native-community/async-storage/(?!(lib))"]

Sure @Krizzu! As you said in your comment I’ve created __mocks__/@react-native-community/async-storage/index.js

let cache = {};
export default {
  setItem: (key, value) => {
    return new Promise((resolve, reject) => {
      return (typeof key !== 'string' || typeof value !== 'string')
        ? reject(new Error('key and value must be string'))
        : resolve(cache[key] = value);
    });
  },
  getItem: (key, value) => {
    return new Promise((resolve) => {
      return cache.hasOwnProperty(key)
        ? resolve(cache[key])
        : resolve(null);
    });
  },
  removeItem: (key) => {
    return new Promise((resolve, reject) => {
      return cache.hasOwnProperty(key)
        ? resolve(delete cache[key])
        : reject('No such key!');
    });
  },
  clear: (key) => {
    return new Promise((resolve, reject) => resolve(cache = {}));
  },

  getAllKeys: (key) => {
    return new Promise((resolve, reject) => resolve(Object.keys(cache)));
  },
}

An then in my tests I just import and mock @react-native-community/async-storage like this:

import AsyncStorage from '@react-native-community/async-storage';
jest.mock('@react-native-community/async-storage');

getting @RNCommunity/AsyncStorage: NativeModule.RCTAsyncStorage is null. after adding transformIgnorePatterns

@Krizzu I’m still have issues, are you aware of this problem:

 FAIL  src/slides/AskNotifications/AskNotificationsConnected.tests.js
  ● Test suite failed to run

    .../node_modules/@react-native-community/async-storage/jest/async-storage-mock.js:6
    type KeysType = Array<string>;
         ^^^^^^^^

    SyntaxError: Unexpected identifier

The solution here was switching to a different mocking package but I’m hoping that’s not necessary.

@opiruyan Thanks!

This is from latest release (1.2.2), where we notice devs to link the library in order to use it.

I’ll try to come up with custom mocks + docs to help people test this library on the weekend.

thanks.

@frozenzia How does your setup looks like? Is it monorepo by any chance?

type KeysType = Array<string>;
     ^^^^^^^^

SyntaxError: Unexpected identifier

Looks like an issue with Flow type striping. Do you have it included in your project?

@cinder92 , no, actually. I got fed up / out-of-time trying to figure out what was going on with the mock included in the package, and just went with a modified version of @vgm8’s mock. We only needed setItem, getItem, and removeItem, AND we have some airBnB eslint rules in place so that the end result was that __mocks__/@react-native-community/async-storage.js (note name! opted for this instead of making an additional async-storage folder and putting index.js in it) looks like this:

const cache = {};
export default {
    setItem: (key, value) => new Promise((resolve, reject) => {
        const retVal = (typeof key !== 'string' || typeof value !== 'string')
            ? reject(new Error('key and value must be string'))
            : resolve(cache[key] = value);
        return retVal;
    }),
    getItem: key => new Promise(resolve => (
        Object.prototype.hasOwnProperty.call(cache, key)
            ? resolve(cache[key])
            : resolve(null))),
    removeItem: key => new Promise((resolve, reject) => (
        Object.prototype.hasOwnProperty.call(cache, key)
            ? resolve(delete cache[key])
            : reject(new Error('No such key!')))),
};

It seems like the issue comes from the lack of transformation by Jest. We have a docs on how to fix this here. Let me know if it worked.

We see the same KeysType error. Also fixable by using @vgm8’s mock.

looks like RN took care of transformIgnorePatters-part of the issue https://github.com/facebook/react-native/releases/tag/v0.59.4

@Krizzu thanks but your link seems to be broken.