nri*_*ion 14 javascript reactjs jestjs react-native enzyme
我有一个组件,它使用Animated来自react native 的组件.我开始编写一个测试用例来模拟onPress一个组件,它调用一个包含Animated.timing在其中的函数setState.
运行jest正常,但测试永远不会停止运行,我之前写过的一个不相关的测试用例现在似乎永远不会通过(之前通过).
运行jest --watch,我收到此错误:
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.
at Function.bezier (node_modules/react-native/Libraries/Animated/src/Easing.js:113:21)
at ease (node_modules/react-native/Libraries/Animated/src/Easing.js:34:24)
at TimingAnimation._easing (node_modules/react-native/Libraries/Animated/src/Easing.js:133:18)
at TimingAnimation.onUpdate (node_modules/react-native/Libraries/Animated/src/animations/TimingAnimation.js:107:45)
RUNS src/__tests__/SlideDownMenu.test.js
/home/nrion/Desktop/mobile-ui/PriceInsight_app/node_modules/react-native/Libraries/Animated/src/Easing.js:114
return _bezier(x1, y1, x2, y2);
^
TypeError: _bezier is not a function
at Function.bezier (/home/nrion/Desktop/mobile-ui/PriceInsight_app/node_modules/react-native/Libraries/Animated/src/Easing.js:224:12)
at ease (/home/nrion/Desktop/mobile-ui/PriceInsight_app/node_modules/react-native/Libraries/Animated/src/Easing.js:94:21)
at TimingAnimation._easing (/home/nrion/Desktop/mobile-ui/PriceInsight_app/node_modules/react-native/Libraries/Animated/src/Easing.js:255:16)
at TimingAnimation.onUpdate (/home/nrion/Desktop/mobile-ui/PriceInsight_app/node_modules/react-native/Libraries/Animated/src/animations/TimingAnimation.js:138:14)
at ontimeout (timers.js:386:11)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)
Run Code Online (Sandbox Code Playgroud)
https://repl.it/repls/PartialGrimyMetadata
Jua*_*dor 38
我愿意为答案做出贡献。
好吧,让我们看看错误消息
ReferenceError: You are trying to 'import' a file after the Jest environment has been torn down.
拆除意味着:Jest 已经完成运行,并且您的代码的某些部分正在尝试在 jest 已经完成运行测试后执行。由于其异步特性,这在 Javascript 上很常见。
有时它会在执行承诺回调后发生。例如:
import { someProcess } from 'a-library'
task.job().then(result => {
someProcess(result)
})
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,代码someProcess从a-library.
job如果对象中的方法task花费的时间比 jest 执行的时间长,则其回调(then()调用)将在 jest 之外运行,因为 jest 已经完成运行测试。因此,当someProcess执行时,它将被加载,a-library因此 jest 会抱怨您在 jest 被拆除后试图加载库。
标记为解决方案的答案部分正确,因为调用jest.useFakeTimers()将阻止您的代码等待n您在调用或类似情况下应该等待的秒数setTime,从而使您的代码人为同步。
测试await这些方法调用将帮助您更好地了解错误是在哪里引入的。
对我有用的代码是
describe("Some test set", () => {
let heavyWorkingService = library.workingService();
// We are marking the test function call as async
test(("Name of the test"), async () => {
// we are awaiting heavyWorkingService to finish its job
await heavyWorkingService("some data")
})
})
Run Code Online (Sandbox Code Playgroud)
在我的真实场景中,我的代码是从 firebase 获取数据,并且因为我没有使用模拟进行此测试,所以它在读取的数据返回后尝试导入 firebase .get()。将测试标记为async并使用关键字调用方法await解决了我的问题
当然,有很多方法可以处理这个错误,只是想让您知道这个错误背后的真正原因,以便您可以为您的测试找到正确的解决方案!
TAR*_*RJU 28
有了上面,理解这一点非常重要
jest.useFakeTimers() 使用模拟函数模拟 setTimeout 和其他计时器函数。
如果在一个文件或描述块中运行多个测试, jest.useFakeTimers(); 可以在每次测试之前手动调用或使用设置函数(例如 beforeEach)调用。
nri*_*ion 17
好的,找到了解决方案.
应该用 jest.useFakeTimers()
我正在使用@testing-library/react-native,所以我所做的是在安装文件中使用清理。
// jest.setup.js
import { cleanup } from '@testing-library/react-native';
afterEach(cleanup);
Run Code Online (Sandbox Code Playgroud)
在 jest 测试文件的最后添加以下几行,毕竟测试是编写的。
afterAll(() => {
mongoose.connection.close()
})
Run Code Online (Sandbox Code Playgroud)
并且一次只运行一个测试文件,例如,
> jest --verbose --runInBand -- filename.test.js
以上都不适合我。我的解决方案是在jest-setup.js文件中添加以下代码:
import { Animated } from 'react-native';
Animated.timing = () => ({
start: () => jest.fn(),
});
Run Code Online (Sandbox Code Playgroud)
不要忘记将此文件包含到您的package.json jest 配置中:
...
"jest": {
...,
"setupFiles": [
"<rootDir>/src/tests/jest-setup.js"
]
},
...
Run Code Online (Sandbox Code Playgroud)
我希望它能帮助任何人
在 package.json 或 jest.config.js 中添加"testEnvironment": "jsdom"到jestkey
"jest": {
"testEnvironment": "jsdom",
"preset": "react-native",
...
Run Code Online (Sandbox Code Playgroud)
取自:https : //stackoverflow.com/a/64567257/728287
jest.useFakeTimers这对我来说不是一个选择,因为它会阻止我正在使用的其他库的执行。
我的解决方法是在每次测试后添加一个延迟,以便任何异步操作都有时间在 Jest 环境被拆除之前完成:
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
describe('Test suite', () => {
// Give time to any async operation to complete after each test
afterEach(async () => {
await sleep(2000);
});
// Also close any pending connection (or related) if any
afterAll(async () => {
await closeConnections();
});
it('My test', async () => {
// Test...
});
});
Run Code Online (Sandbox Code Playgroud)
当然,必须根据您的应用调整延迟时间。
| 归档时间: |
|
| 查看次数: |
4561 次 |
| 最近记录: |