Jest:尝试导入本机模块时出错;无法用 Mock 防止 [英] Jest: Error when trying to import Native Modules; unable to prevent with Mock

查看:20
本文介绍了Jest:尝试导入本机模块时出错;无法用 Mock 防止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近被带到一个团队担任测试工程师,我正在尝试在我们的 React Native 应用程序上启动和运行 Jest 单元测试.我的前任已经编写了几十个单元测试,其中大部分都没有成功运行.

I've recently been brought on to a team as Test Engineer and I'm trying to get Jest unit tests up and running on our React Native app. My predecessor has already authored dozens of unit tests, most of which are not running successfully.

运行 npm test

 FAIL  __tests__/index.test.js
  ● Test suite failed to run

TypeError: Cannot read property '_addDeviceToGroup' of undefined

  4 | } from 'react-native';
  5 | const {
> 6 |   _addDeviceToGroup,
    |   ^
  7 | } = NativeModules._BleAssociator
  8 | const {
  9 |   _queryName,

  at Object._addDeviceToGroup (app/utils/mesh.js:6:3)
  at Object.<anonymous> (app/actions/hierarchy.js:26:1)
  at Object.<anonymous> (app/actions/organizations.js:14:1)

问题似乎是在我们实现后端团队编写的自定义原生模块时出现的(同样是在我加入团队之前).

It seems as though the issue arose when we implemented custom Native Modules written by our backend team (again, before my joining the team).

经过一些研究,我决定继续进行,假设这与 Jest 无法解析引擎中的 Objective-C 相关,而引擎中提供给本机模块,而不是我们的堆栈有问题(很高兴考虑这种可能性,虽然).

After some research, I decided to proceed under the assumption that this has to do with Jest's inability to parse the Objective-C in the Engine that's feeding in the Native Modules and not some issue with our stack (happy to consider that possibility, though).

我已经查看了 Jest 文档,专门梳理了几个相关文档(模拟功能使用Jest使用 ES 模块导入测试带有 Jest Mock 的本机模块React 本机模块指南)

I've reviewed the Jest documentation, combing specifically through a couple relevant documents (Mock Functions, Using Jest with ES Module Imports, Testing Native Modules with Jest Mock, React Native Modules Guide)

我的问题似乎与 这个问题;但是,该修复程序对我不起作用.即使在模拟 NativeModules 时,我也会遇到同样的错误.

My issue appears to be identical to this issue; however, the fix is not working for me. Even when mocking the NativeModules, I get the same error.

我已经熟悉 Jest 模拟被提升到导入语句上方的概念,但我不清楚为什么模拟在我上面链接的问题的描述块中(除了可能重置模拟功能)对于每个新测试,以防混淆 .mock 属性的返回数据......我离题了).

I've become familiar with the notion that Jest mocks are hoisted above the import statements, but it's not clear to me why the mocks are in the describe block in the issue I linked above (other than maybe to reset the mock function for each new test in case so as to not confound the .mock property's return data... I digress).

对我来说,在执行任何代码之前,错误似乎发生在导入过程中.为了测试这一点,我来回走了一遍,注释掉了除导入语句和模拟之外的所有内容.这样做,我仍然得到同样的错误.当我使用 beforeEach() mocha 语句时也是这种情况,如上面链接的问题的解决方案.

To me, it seems the error is occurring during the imports, before any of the code is executed. To test this, I've gone back and forth, commenting out everything but the import statements and the mocks. Doing this, I still get the same error. This is also the case when I use a beforeEach() mocha statement, as in the solution to the issue linked above.

唯一可以修复此错误的方法是完全注释掉导入.

The only thing that fixes this error commenting out the imports altogether.

我没有尝试过错误处理(try/catch),因为我不确定如果执行 catch 块,我如何仍然可以成功导入我正在测试的组件.

I have not tried error handling (try/catch), as I'm not certain how I could still successfully import the component I'm testing if the catch block is executed.

抱歉所有这些背景.我为此花了几个工作日,所以我想确保我的所有基础都被覆盖.

Sorry for all that background. I have spent a couple workdays on this, so I want to make certain all my bases are covered.

这是一个示例测试:

/__tests__/app/components/Onboarding/Splash/Splash.test.js

import {
  NativeModules,
} from 'react-native';

import { Splash } from '../../../../../app/components/Onboarding/Splash/Splash.js';
// import login from '../../../../../app/actions/login';

// NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
// login = jest.fn;

export default function({React, shallow}) {

  const props = {
    // some test props
  };

  function make({navigation, getUserInfo, verifyUser, login} = props) {
    return shallow(
      // renders the component with props
    );
  }

  describe('<Splash />', () => {
    // I added this part (didn't help)
    beforeEach(() => {
      NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
      login = jest.fn;
    });
    // end part I added
    
    // stuff (all the tests are in here)

  });

}

NativeModules 和登录导入、注释掉的行和 beforeEach() 块是我间歇性尝试但无济于事的事情.

The NativeModules and login imports, the commented out lines, and the beforeEach() block are things I've tried intermittently to no avail.

在尝试跟踪此错误时,我发现在运行脚本的原始 Splash.js 中注释掉 import 语句(因为 ES6 import 运行它引用的脚本),尝试导入 NativeModules 修复了我看到的错误.正如您可能从堆栈跟踪中收集到的那样,这些有很多层次.

When trying to trace this error, I found that commenting out import statement in the original Splash.js that run scripts (as ES6 import runs the script it references) that try to import NativeModules fixes the error I see. As you might have gleaned from the stack trace, these go many levels deep.

呼.如果您已经读到这里,我真的很感谢您的帮助.

PHEW. If you've read this far, I really appreciate the help.

很抱歉问这么长而复杂的问题.如您所见,我们有一个庞大而复杂的堆栈.由于在出现错误之前发生了多少链式导入,上述问题的修复程序可能不起作用.

Sorry to have such a long and complicated question. As you can see, we have a large and convoluted stack. It's possible the fix from the issue above isn't working because of how many chained imports happen before getting to the error.

如果它是我遗漏的一个小修复,或者如果有某种我不知道的浅"式导入,我会喜欢它.

I'd love it if it's a tiny fix that I'm missing or if there was some sort of "shallow"-ish import that I'm not aware of.

感谢无数人的帮助.欢迎任何意见.

Thanks a bajillion for your help. Any input is welcome.

推荐答案

我找到了解决方案.我一直担心可能没有通过所有导入语句跟踪模拟.真正发生的事情是我错误地格式化了模拟.

I found the solution to this. I had been worried that perhaps the mocks weren't being tracked through all the import statement. What was really happening was I was formatting the mocks wrong.

我在标准 Jest 文档中没有看到这个,而是发现它此处.

I did not see this in the standard Jest documentation, but instead found it here.

将此添加到我的 *.test.js 文件中有效:

Adding this to my *.test.js files worked:

import { NativeModules } from 'react-native';
jest.mock('NativeModules', () => {
  return {
    _BleAssociator: {
      _addDeviceToGroup: jest.fn()
    },
    // ... and so on for all the other methods expected in NodeModules
  };
});

为了后代,我认为最好将其保存在自己的脚本中并导入到测试中......我还没有尝试过.

Just for posterity's sake, I think this would be best kept in its own script and imported into the tests... I haven't tried this yet.

这篇关于Jest:尝试导入本机模块时出错;无法用 Mock 防止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆