安装react-native-async-storage后jest测试失败

w51jfk4q  于 2023-03-27  发布在  Jest
关注(0)|答案(7)|浏览(157)

在我的react native项目中,我最近安装了节点模块react-native-async-storage,因为我收到了关于'react-native'中的native包被弃用并移出到单个模块的警告。
安装@react-native-community/async-storage后,我的jest测试失败。
第一个,后面是error: unexpected token at position 0
文件中:

persistence.js

import AsyncStorage from '@react-native-community/async-storage';

storeData = async ({ key, value }) => {
  try {
    await AsyncStorage.setItem(key, value);
  } catch (error) {
    // Error saving data
  }
}

retrieveData = async (key) => {
  try {
    const value = await AsyncStorage.getItem(key);
    if (value !== null) {
      // Our data is fetched successfully
      return value;
    }
  } catch (error) {
    // Error retrieving data
  }
}

module.exports = {
  storeData,
  retrieveData
}

所以我假设这与某些babel配置有关,因为我上次从@react-native-community安装软件包时遇到了类似的情况
因此,我在package.json中的transformIgnorePatterns中添加了以下内容:

"jest": {
    "preset": "react-native",
    "transformIgnorePatterns": [
      "node_modules/(?!react-native|@react-native-community/async-storage|native-base-shoutem-theme|@shoutem/animation|@shoutem/ui|tcomb-form-native)"
    ]
  }

但现在我得到一个新的错误。@RNCommunity/AsyncStorage: NativeModule.RCTAsyncStorage is null.
我粘贴屏幕截图来显示我的项目目录,这样你就可以了解哪些配置文件可以用来搞乱。x1c 0d1x
正如我所看到的,大多数相关的主题都是关于模拟asyncStorage函数的,我试过这样做,没有任何运气。我在我唯一的测试文件中添加了以下内容:

import MockAsyncStorage from 'mock-async-storage';

beforeAll(() => { 
  const mockImpl = new MockAsyncStorage()
  jest.mock('AsyncStorage', () => mockImpl)
  snapshot = renderer.create(<App />);
})

afterAll(() => {
  jest.unmock('AsyncStorage')
});

还是没有雪茄。我试过添加一个setupFilesAfterEnv.js与配置作为其他答案建议,也没有做的伎俩。

w9apscun

w9apscun1#

async-storage有published instructions关于如何解决这个问题。
下面是一个简短的版本:
1.在项目根目录下,创建**mocks/@react-native-community目录。
1.在该文件夹中,创建一个
async-storage.js**文件。
1.将以下内容复制粘贴到该文件中:

export default from '@react-native-community/async-storage/jest/async-storage-mock'

1.好好享受吧!
我希望它能帮助其他人。

tyu7yeag

tyu7yeag2#

我找到了一种嘲笑@react-native-community/async-storage的方法
在我项目根目录下(与__test__目录相同),我创建了一个目录结构,如下所示:
__mocks__/@react-native-community/async-storage/index.js
在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)));
  },
}

在我的测试文件中,我添加了以下内容:

beforeAll(() => { 
  jest.mock('@react-native-community/async-storage');
})

dir结构截图:

这一招奏效了。我在这里找到了灵感:https://github.com/react-native-community/react-native-async-storage/issues/39

iugsix8n

iugsix8n3#

您需要将这段代码添加到setupTestFrameworkScriptFile中

import { NativeModules } from 'react-native';
NativeModules.RNCAsyncStorage = {
  getItem: jest.fn(),
  setItem: jest.fn(),
  removeItem: jest.fn(),
  mergeItem: jest.fn(),
  clear: jest.fn(),
  getAllKeys: jest.fn(),
  flushGetRequests: jest.fn(),
  multiGet: jest.fn(),
  multiSet: jest.fn(),
  multiRemove: jest.fn(),
  multiMerge: jest.fn(),
};
xytpbqjk

xytpbqjk4#

您可以将其添加到测试文件中。

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

举个例子

import React from "react";

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

describe("Example test", () => {
  it("should work", () => {
    ...
  });
});
gtlvzcf8

gtlvzcf85#

谢谢@Krizzo
另一个基于@Rasmus普尔斯的Jest版本,但具有jest函数-将添加到您的jest mocks文件中。

jest.mock('@react-native-community/async-storage', () => { 
  let cache = {};
  return {
    setItem: jest.fn((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: jest.fn((key, value) => {
      return new Promise((resolve) => {
        return cache.hasOwnProperty(key)
          ? resolve(cache[key])
          : resolve(null);
      });
    }),
    removeItem: jest.fn((key) => {
      return new Promise((resolve, reject) => {
        return cache.hasOwnProperty(key)
          ? resolve(delete cache[key])
          : reject('No such key!');
      });
    }),
    clear: jest.fn((key) => {
      return new Promise((resolve, reject) => resolve(cache = {}));
    }),
    getAllKeys: jest.fn((key) => {
      return new Promise((resolve, reject) => resolve(Object.keys(cache)));
    }),
  }
});
n1bvdmb6

n1bvdmb66#

看看documentation by the team,(来自Francois Nadeau提供的答案)我能够将'mocking with jest setup.js file'选项更改为下面的行,并解决了完全相同的问题。

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

请注意,路径已更改。

qacovj5a

qacovj5a7#

我不得不修改published solution
1.在项目根目录中,创建__mocks__/@react-native-async-storage目录。
1.在该文件夹中,创建async-storage.js文件。
1.在该文件中,粘贴以下内容:

export * as default from '@react-native-async-storage/async-storage/jest/async-storage-mock'

注意:我在使用原始解决方案时遇到了一个ts1005编译错误,抱怨缺少分号(即export default from '@ ...)。我使用的是Typescript 4.9,所以这可能会给我的原始解决方案带来问题。

相关问题