从32升级到Expo SDK 33后,在jest中运行测试有问题。当模拟get返回值时,Jest抱怨Response不是构造函数。
const mockGet = jest.fn();
mockGet.mockReturnValue(new Response(
JSON.stringify({
data: true
}),
{ status: 200 }
));下面是相关包的当前package.json的一个片段。
{
"devDependencies": {
"@babel/core": "^7.2.2",
"@types/enzyme": "3.9.1",
"@types/expo": "^32.0.13",
"@types/jest": "23.3.10",
"@types/react": "^16.5.0",
"@types/react-native": "^0.57.20",
"babel-core": "^7.0.0-0",
"babel-eslint": "10.0.1",
"babel-jest": "23.6.0",
"babel-preset-expo": "^5.0.0",
"enzyme": "3.9.0",
"enzyme-adapter-react-16": "1.12.1",
"enzyme-to-json": "3.3.5",
"eslint": "5.11.0",
"jest": "24.8.0",
"jest-cli": "24.8.0",
"jest-expo": "^33.0.0",
"react-dom": "16.8.6",
"raf": "3.3.2",
"ts-jest": "^24.0.2",
"tslint": "5.12.0",
"typescript": "3.5.2"
},
"scripts": {
"jest": "node node_modules/jest-expo/bin/jest.js --runInBand",
"lint": "tslint src/**/*.ts",
"test": "npm run jest && tslint src/**/*.tsx && eslint .",
},
"jest": {
"preset": "jest-expo",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
"setupFiles": [
"raf/polyfill",
"<rootDir>/test-setup.js"
],
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
"\\.(ts|tsx)$": "ts-jest"
}
},
"dependencies": {
"expo": "^33.0.0",
"react": "16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz",
}在从32升级到33之前,这些使用Response对象的测试都是成功工作的。现在,在升级之后,测试套件将引发TypeError。
唯一更改版本的模块是jest-expo (32.0.0 -> ^33.0.0)、ts-jest (23.10.5 -> ^24.0.2)、typescript (3.4.3 -> 3.5.2)和最后的expo (^32.0.0 -> ^33.0.0)。react-native模块也从Expo的react-native archive sdk-32更新到sdk-33。
我尝试了不同版本的模块,试图查看响应的定义在哪里发生了变化。例如,我将jest-expo从v33降级为v32,而expo为v33。这没有什么帮助,因为它导致测试套件完全失败,如下所示。
● Test suite failed to run
Cannot find module 'expo-react-native-adapter' from 'setup.js'
at Resolver.resolveModule (node_modules/@jest/core/node_modules/jest-resolve/build/index.js:230:17)
at Object.<anonymous> (node_modules/jest-expo/src/setup.js:203:6)任何关于如何阻止TypeError在测试期间出现的帮助都将不胜感激。注意到TypeScript在intellij中检测不到此类型错误,这也可能是有帮助的。
发布于 2020-01-16 09:03:05
我发现的问题是jest-expo模块中的mock是如何定义的。我可以通过创建一个补丁(使用patch-package模块)来解决这个问题。补丁在下面。您可以将其添加到根目录下的"patches/jest-expo+33.X.X.patch“中,并在package.json文件中添加"postinstall":"patch-package”post-install挂钩。
diff --git a/node_modules/jest-expo/src/preset/setup.js b/node_modules/jest-expo/src/preset/setup.js
index 1d791d4..bb3d9a0 100644
--- a/node_modules/jest-expo/src/preset/setup.js
+++ b/node_modules/jest-expo/src/preset/setup.js
@@ -5,7 +5,6 @@
'use strict';
// whatwg-fetch@3 expects "self" to be globally defined
-global.self = global;
const { Response, Request, Headers, fetch } = require('whatwg-fetch');
global.Response = Response;
@@ -148,18 +147,16 @@ mockNativeModules.NativeUnimoduleProxy.modulesConstants = {
};
jest.mock('expo-file-system', () => ({
- FileSystem: {
- downloadAsync: jest.fn(() => Promise.resolve({ md5: 'md5', uri: 'uri' })),
- getInfoAsync: jest.fn(() => Promise.resolve({ exists: true, md5: 'md5', uri: 'uri' })),
- readAsStringAsync: jest.fn(),
- writeAsStringAsync: jest.fn(),
- deleteAsync: jest.fn(),
- moveAsync: jest.fn(),
- copyAsync: jest.fn(),
- makeDirectoryAsync: jest.fn(),
- readDirectoryAsync: jest.fn(),
- createDownloadResumable: jest.fn(),
- },
+ downloadAsync: jest.fn(() => Promise.resolve({ md5: 'md5', uri: 'uri' })),
+ getInfoAsync: jest.fn(() => Promise.resolve({ exists: true, md5: 'md5', uri: 'uri' })),
+ readAsStringAsync: jest.fn(() => Promise.resolve()),
+ writeAsStringAsync: jest.fn(() => Promise.resolve()),
+ deleteAsync: jest.fn(() => Promise.resolve()),
+ moveAsync: jest.fn(() => Promise.resolve()),
+ copyAsync: jest.fn(() => Promise.resolve()),
+ makeDirectoryAsync: jest.fn(() => Promise.resolve()),
+ readDirectoryAsync: jest.fn(() => Promise.resolve()),
+ createDownloadResumable: jest.fn(() => Promise.resolve()),
}));
jest.mock('react-native/Libraries/Image/AssetRegistry', () => ({https://stackoverflow.com/questions/56880598
复制相似问题