用酶开玩笑的React Native在构造函数中抛出丢失的super()调用

时间:2019-01-24 15:50:51

标签: javascript react-native jestjs enzyme jsdom

在完成所有设置和工作时遇到了一些麻烦,这是我的环境

Environment:
  OS: macOS 10.14.2
  Node: 8.9.0
  Yarn: 1.5.1
  npm: 6.4.1
  Watchman: 4.9.0
  Xcode: Xcode 10.1 Build version 10B61
  Android Studio: 3.2 AI-181.5540.7.32.5056338

Packages: (wanted => installed)
  react: 16.3.1 => 16.3.1
  react-native: 0.55.4 => 0.55.4

这是我的jest中的package.json配置

"jest": {
    "preset": "react-native",
    "transformIgnorePatterns": [
      "node_modules/(?!react-native|react-navigation)/"
    ],
    "coverageThreshold": {
      "global": {
        "statements": 80
      }
    },
    "moduleFileExtensions": [
      "js",
      "jsx"
    ],
    "moduleDirectories": [
      "node_modules"
    ],
    "snapshotSerializers": ["enzyme-to-json/serializer"],
    "setupTestFrameworkScriptFile": "./setup-tests.js",
    "setupFiles": ["./setup.js"]
  }

setup-tests.js文件中,我进行了此设置

import 'react-native';
import 'jest-enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Enzyme from 'enzyme';

/**
 * Set up DOM in node.js environment for Enzyme to mount to
 */
const { JSDOM } = require('jsdom');

const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
const { window } = jsdom;

function copyProps(src, target) {
  Object.defineProperties(target, {
    ...Object.getOwnPropertyDescriptors(src),
    ...Object.getOwnPropertyDescriptors(target),
  });
}

global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};
copyProps(window, global);

/**
 * Set up Enzyme to mount to DOM, simulate events,
 * and inspect the DOM in tests.
 */
Enzyme.configure({ adapter: new Adapter() });

/**
 * Ignore some expected warnings
 * see: https://jestjs.io/docs/en/tutorial-react.html#snapshot-testing-with-mocks-enzyme-and-react-16
 * see https://github.com/Root-App/react-native-mock-render/issues/6
 */
const originalConsoleError = console.error;
console.error = (message) => {
  if (message.startsWith('Warning:')) {
    return;
  }

  originalConsoleError(message);
};

还有setup.js

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });

我从酵素网站的这个页面上得到的

https://airbnb.io/enzyme/docs/guides/react-native.html

依赖版本为

"babel-core": "^6.26.3",
"babel-jest": "23.6.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react-native": "4.0.1",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"enzyme-to-json": "^3.3.5",
"jest": "23.6.0",
"jest-enzyme": "^7.0.1",
"jest-serializer-enzyme": "^1.0.0",
"jsdom": "^13.2.0",
"react-addons-test-utils": "^15.6.2",
"react-dom": "^16.7.0",
"react-native-mock-render": "^0.1.2",
"react-test-renderer": "16.3.1"

我遇到的具体错误是

***/node_modules/jsdom/lib/jsdom/living/generated/Element.js: missing super() call in constructor

        15 | 
        16 | class Element extends Node.interface {
      > 17 |   constructor() {
           |   ^
        18 |     throw new TypeError("Illegal constructor");
        19 |   }
        20 | 

为此,我尝试了许多不同的配置,但似乎无法克服此错误。

这是测试文件

import 'react-native';
import React from 'react';
import {Login} from './index';
import { mount } from 'enzyme';


it('renders correctly', () => {
  const wrapper = mount(
    <Login />
  );
  expect(wrapper).toMatchSnapshot();
});

我已经对正在测试的文件进行配对,以尝试消除任何可能的外部库问题

import React from 'react';
import {
  View,
  Text
} from 'react-native';

export class Login extends React.Component {
  render() {
    return (
      <View>
        <Text>Hello World</Text>
      </View>
    );
  }
}

export default Login;

这里的命名导出和默认导出没有区别,但是通常默认导出连接到redux,所以我导出命名类进行测试。

1 个答案:

答案 0 :(得分:0)

显示的依赖性表明您正在使用Babel6。Babel6中存在一个错误,该错误会导致您在问题中描述的问题类型。据报道herehere

您应该升级到Babel 7。


简而言之,问题是在Babel修复之前,Babel对代码进行了静态分析,发现未调用super()并在静态分析期间使代码失败。但是,规则是在访问super()或从构造函数返回this之前必须调用this。 (如果构造函数未显式返回值,则它将返回this。)由于显示失败的构造函数会抛出该异常,因此它不会返回,因此不必调用super()