ReferenceError:您试图在Jest环境被拆除后“导入”文件

时间:2018-06-11 08:58:54

标签: javascript reactjs react-native jestjs enzyme

我有一个组件,它使用来自本机的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)

链接到repl

https://repl.it/repls/PartialGrimyMetadata

环境:

  • 操作系统:Linux 4.14
  • 节点:6.14.2
  • 纱线:1.7.0
  • npm:3.10.10
  • 守望者:未找到
  • Xcode:N / A
  • Android Studio:未找到

7 个答案:

答案 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",
   ...

取自:https://stackoverflow.com/a/64567257/728287

答案 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()

首先,了解这一点非常重要

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);
    });
  });
}