我有一个组件,它使用来自本机的Animated
组件。我开始编写一个测试用例来模拟组件的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)
https://repl.it/repls/PartialGrimyMetadata
答案 0 :(得分:12)
好的,找到了解决方案。
应该使用jest.useFakeTimers()
答案 1 :(得分:5)
我使用的是 @testing-library/react-native
,所以我所做的是在安装文件中使用清理。
// jest.setup.js
import { cleanup } from '@testing-library/react-native';
afterEach(cleanup);
答案 2 :(得分:2)
在 jest 测试文件的最后添加以下几行, 毕竟,测试是写出来的。
afterAll(() => {
mongoose.connection.close()
})
并且也只是一次运行一个测试,例如,
> jest --verbose --runInBand -- filename.test.js
答案 3 :(得分:1)
将 "testEnvironment": "jsdom"
添加到 package.json 或 jest.config.js 中的 jest
键
"jest": {
"testEnvironment": "jsdom",
"preset": "react-native",
...
答案 4 :(得分:1)
我想为答案做出贡献。
好吧,让我们看看错误信息
ReferenceError: You are trying to 'import' a file after the Jest environment has been torn down.
Torn down 意味着:Jest 已经完成运行,并且在 Jest 被拆除或退出测试后,您的部分代码正在尝试执行。由于其异步性质,这在 Javascript 上很常见。
有时会在执行 Promise 回调之后发生,例如:
import { someProcess} from 'a-library'
task.job().then(result => {
someProcess(result)
})
在上面的示例中,代码从 someProcess
导入 a-library
如果来自 job
对象的方法 task
花费的时间比玩笑执行时间长,则其回调(then() 调用)将在玩笑之外运行,因为玩笑已经继续。因此,当 someProcess
被执行时,它将从 a-library
加载,所以 jest 会抱怨你在 jest 被撕毁后试图加载一个库。
标记为解决方案的答案部分正确,因为调用 jest.useFakeTimers()
将阻止您的代码等待 n 秒您应该等待调用 setTime 或类似方法使您的代码人为地错误
让您的测试await
这些方法调用将帮助您更好地理解您的代码。
对我有用的代码是
describe("Some test set " , ()=>{
let heavyWorkinService = library.workingService();
// We are marking the test function call as async
test(("Name of the test"), async ()=>{
// we are awaiting heavyWorkingService to done its job
await hevyWorkingService("some data")
})
})
在我的真实场景中,我的代码是从 firebase 获取数据,因为我没有使用模拟进行此测试,它试图在 .get() 数据读取返回后导入 firebase,因此将测试标记为 async
并调用带有 await
关键字的方法解决了我的问题
当然有很多方法可以处理这个错误,只是想让你知道这个错误背后的真正原因,这样你就可以为你的测试找到正确的解决方案!
答案 5 :(得分:0)
首先,了解这一点非常重要
jest.useFakeTimers()使用模拟函数模拟setTimeout和其他计时器函数。
如果在一个文件或描述块内运行多个测试,请jest.useFakeTimers();可以在每次测试之前手动调用,也可以使用诸如beforeEach之类的设置函数调用。
答案 6 :(得分:0)
在用react-native-testing-library
测试Apollo时遇到了这个问题。
在这种情况下,父组件和子组件中有两个查询。父查询需要在子查询呈现并触发其查询之前进行解析。
解决方案是两次运行wait()
函数,而不是一次。我认为必须进行两次验证以确保两个查询都运行。该错误消息非常不透明。
test("...", () => {
const rr = render(...);
await wait();
await wait(); // Child query must also run
expect(...);
}
// Wait a tick so the query runs
// https://www.apollographql.com/docs/react/development-testing/testing/#testing-final-state
export async function wait(ms = 0) {
await act(async () => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
});
}