安装 react-native-async-storage 后开玩笑测试失败
jest test fails after installing react-native-async-storage
在我的 React Native 项目中,我最近安装了节点模块 react-native-async-storage,因为我从 'react-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.
我正在粘贴屏幕截图以显示我的项目目录,以便您了解哪些配置文件可以乱用。
据我所知,大多数相关主题都是关于模拟 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
与其他答案建议的配置,也没有成功。
您需要将这段代码添加到您的 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(),
};
我找到了一种模拟 @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');
})
目录结构截图:
这成功了。我在这里找到了灵感:https://github.com/react-native-community/react-native-async-storage/issues/39
async-storage published instructions 关于如何解决这个问题。
这是一个简短的版本:
- 在你的项目根目录下,创建__mocks__/@react-native-community目录。
- 在该文件夹中,创建一个 async-storage.js 文件。
- 将以下内容复制粘贴到该文件中:
export default from '@react-native-community/async-storage/jest/async-storage-mock'
- 尽情享受吧!
希望对大家有所帮助
编辑
忽略我的回答,而是这样做:
https://github.com/react-native-community/async-storage/blob/LEGACY/docs/Jest-integration.md
感谢@Krizzo
基于@Rasmus Puls 的另一个 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)));
}),
}
});
您可以将其添加到您的测试文件中。
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", () => {
...
});
});
查看 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);
请注意路径已更改。
在我的 React Native 项目中,我最近安装了节点模块 react-native-async-storage,因为我从 'react-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.
我正在粘贴屏幕截图以显示我的项目目录,以便您了解哪些配置文件可以乱用。
据我所知,大多数相关主题都是关于模拟 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
与其他答案建议的配置,也没有成功。
您需要将这段代码添加到您的 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(),
};
我找到了一种模拟 @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');
})
目录结构截图:
这成功了。我在这里找到了灵感:https://github.com/react-native-community/react-native-async-storage/issues/39
async-storage published instructions 关于如何解决这个问题。
这是一个简短的版本:
- 在你的项目根目录下,创建__mocks__/@react-native-community目录。
- 在该文件夹中,创建一个 async-storage.js 文件。
- 将以下内容复制粘贴到该文件中:
export default from '@react-native-community/async-storage/jest/async-storage-mock'
- 尽情享受吧!
希望对大家有所帮助
编辑 忽略我的回答,而是这样做: https://github.com/react-native-community/async-storage/blob/LEGACY/docs/Jest-integration.md
感谢@Krizzo
基于@Rasmus Puls 的另一个 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)));
}),
}
});
您可以将其添加到您的测试文件中。
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", () => {
...
});
});
查看 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);
请注意路径已更改。