【问题标题】:React Native jest keep throwing -TypeError: Component is not a function errorReact Native 玩笑不断抛出 -TypeError: Component is not a function 错误
【发布时间】:2016-10-09 00:52:16
【问题描述】:

当我尝试使用 jest 添加一个简单的单元测试时,我目前遇到了一个问题。它不断抛出 TypeError:Component is not a function 错误,我无法修复它。之前有人遇到过同样的错误,或者有人对如何修复它有任何想法吗?真的很感激!

我从 jest 得到的测试结果是这样的:

Using Jest CLI v11.0.2, jasmine2, babel-jest
Running 1 test suite...Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).
 FAIL  app/views/connections/__tests__/Connections-test.js (3.217s)
Connections
  ✕ it should return View

Connections › it should return View
  - TypeError: Component is not a function
        at ShallowComponentWrapper._constructComponentWithoutOwner (node_modules/react/lib/ReactCompositeComponent.js:250:8)
        at ShallowComponentWrapper.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:159:15)
        at ShallowComponentWrapper.wrapper [as mountComponent] (node_modules/react/lib/ReactPerf.js:66:13)
        at ReactShallowRenderer._render (node_modules/react/lib/ReactTestUtils.js:385:10)
        at _batchedRender (node_modules/react/lib/ReactTestUtils.js:366:10)
        at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react/lib/Transaction.js:136:12)
        at Object.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:63:13)
        at Object.batchedUpdates (node_modules/react/lib/ReactUpdates.js:97:18)
        at ReactShallowRenderer.render (node_modules/react/lib/ReactTestUtils.js:359:14)
        at renderConnections (app/views/connections/__tests__/Connections-test.js:17:10)
        at Object.eval (app/views/connections/__tests__/Connections-test.js:25:12)
1 test failed, 0 tests passed (1 total in 1 test suite, run time 9.326s)
--------------------|----------|----------|----------|----------|----------------|
File                |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
--------------------|----------|----------|----------|----------|----------------|
 __mocks__/         |    78.33 |    48.15 |    46.15 |      100 |                |
  react-native.js   |    78.33 |    48.15 |    46.15 |      100 |                |
 views/connections/ |    88.89 |       75 |       50 |       80 |                |
  Connections.js    |    88.89 |       75 |       50 |       80 |              9 |
--------------------|----------|----------|----------|----------|----------------|
All files           |    79.71 |    51.61 |    46.67 |    96.15 |                |
--------------------|----------|----------|----------|----------|----------------|

我要测试的组件如下:

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

const Connections = React.createClass({
  render () {
    return (
      <View>
        <Text>
          Connections Page
        </Text>
      </View>
    )
  }
})

export default Connections

而我的 package.json 如下:

{
    "name": "someProject",
    "version": "0.0.6",
    "private": true,
    "scripts": {
        "start": "node node_modules/react-native/local-cli/cli.js start",
        "test_legacy": "mocha --comilers js:babel-core/register --recursive ./test/units/*.js --require ./test/setup.js",
        "test": "rm -rf ./node_modules/jest-cli/.haste_cache && jest  --no-cache",
        "build-prd": "cd android && ./gradlew installRelease",
        "clean-install": "rm -r -f node_modules && npm install"
    },
    "dependencies": {
        "axios": "^0.11.0",
        "install": "^0.7.3",
        "moment": "^2.13.0",
        "npm": "^3.8.9",
        "react": "15.0.2",
        "react-native": "^0.26.2",
        "react-native-animatable": "^0.6.0",
        "react-native-billing": "^1.3.0",
        "react-native-button": "^1.5.0",
        "react-native-carousel": "^0.8.0",
        "react-native-device-info": "^0.9.3",
        "react-native-dismiss-keyboard": "^1.0.0",
        "react-native-drawer": "^2.2.0",
        "react-native-gifted-spinner": "0.0.4",
        "react-native-i18n": "0.0.8",
        "react-native-linear-gradient": "^1.5.9",
        "react-native-modalbox": "^1.3.3",
        "react-native-push-notification": "^1.0.6",
        "react-native-router-flux": "^3.26.0",
        "react-native-scrollable-tab-view": "^0.4.2",
        "react-native-swipeout": "^2.0.12",
        "react-native-swiper": "^1.4.4",
        "react-native-vector-icons": "^2.0.2",
        "react-redux": "^4.4.5",
        "realm": "^0.12.0",
        "redux": "^3.5.2",
        "redux-logger": "^2.6.1",
        "redux-promise": "^0.5.3",
        "redux-thunk": "^2.0.1",
        "socket.io-client": "^1.3.5"
    },
    "devDependencies": {
        "babel": "^6.5.2",
        "babel-core": "^6.9.0",
        "babel-jest": "^12.1.0",
        "babel-polyfill": "^6.9.1",
        "babel-preset-airbnb": "^1.0.1",
        "babel-preset-es2015": "^6.9.0",
        "babel-preset-react": "^6.5.0",
        "babel-preset-react-native": "^1.9.0",
        "babel-preset-stage-0": "^6.5.0",
        "chai": "^3.5.0",
        "enzyme": "^2.3.0",
        "jest-cli": "11.0.2",
        "mocha": "^2.4.5",
        "react-addons-test-utils": "15.0.2",
        "react-dom": "15.0.2"
    },
    "jest": {
        "setupEnvScriptFile": "node_modules/react-native/jestSupport/env.js",
        "testPathIgnorePatterns": ["/node_modules/"],
        "testFileExtensions": [
            "es6", "js"
        ],
        "moduleFileExtensions": [
            "js", "json", "es6"
        ],
        "unmockedModulePathPatterns": [
            "react",
            "react-addons-test-utils",
            "react-native-router-flux",
            "fetch",
            "redux",
            "redux-thunk"
        ],
        "collectCoverage": true,
        "verbose": true,
        "haste": {
            "defaultPlatform": "android",
            "platforms": [
                "ios", "android"
            ],
            "providesModuleNodeModules": ["react-native"]
        }
    }
}

最后我的示例测试用例是这样的:

jest.autoMockOff();

import React, { View } from 'react-native';
import utils from 'react-addons-test-utils';
// import React, {View} from 'react-native';
// import utils from 'react-addons-test-utils';

jest.dontMock('../Connections');
// import Connections from '../Connections';
const Connections = require('../Connections');

describe('Connections', (props) => {
  function renderConnections() {
    const renderer = utils.createRenderer();
    renderer.render(<Connections {...props}/>);
    const output = renderer.getRenderOutput();
    return {
      props,
      output,
      renderer
    };
  }
  it('should return View', () => {
    const output = renderConnections({someProps: true});
    expect(output).toEqual(View);
  })
})

我的模拟 react-native.js 看起来像:

'use strict';
/**
 * ## Imports
 *
 * ReactNative is actually React
 */
const React = require('react');
const ReactNative = React;

/**
 * ## These need additional mocking
 *
 * ReactNative is actually React
 */
ReactNative.StyleSheet = {
    create: function create(styles) {
        return styles;
    }
};
class View extends React.Component {
    render() { return false; }
}
class PixelRatio extends React.Component {
    static get() { return 1; }
}
/**
 * ## Stubs
 *
 * Simple replacements for testing
 */
ReactNative.View = View;
ReactNative.ScrollView = View;
ReactNative.Text = View;
ReactNative.TouchableOpacity = View;
ReactNative.TouchableHighlight = View;
ReactNative.TouchableWithoutFeedback = View;
ReactNative.ToolbarAndroid = View;
ReactNative.Image = View;
ReactNative.PixelRatio = PixelRatio;
ReactNative.NativeModules= {};

ReactNative.Platform = {};
module.exports = ReactNative;

【问题讨论】:

标签: javascript unit-testing react-native jestjs


【解决方案1】:

使用yarn startnpm start 重新启动metro bundler 解决了我的问题

【讨论】:

    【解决方案2】:

    我猜你在测试中的导入:

    jest.autoMockOff();
    
    import React, { View } from 'react-native';
    

    实际上可能没有导入您的自定义 react-native.js

    您想使用相对的./react-native 导入来代替吗?

    【讨论】:

    • 感谢您的回复。我终于想通了解决方案是我必须在测试文件上使用jest.unmock('../Connections') 而不是jest.dontMock('../Connections');。 Jest 的官方文档中关于 jest.unmock 的说法是这样的: 注意:这个方法之前被称为 dontMock。使用 babel-jest 时,对 unmock 的调用将自动提升到代码块的顶部。如果您想明确避免这种行为,请使用 dontMock。 所以在我将其更改为 unmock 后,一切正常。
    • sunnyyants,即使在更改为 unmock 之后,您的示例也会出现同样的错误。还有其他要更改的设置/代码吗?
    【解决方案3】:

    如果您忘记从模块中导出组件,也可以出现Component is not a function

    【讨论】:

      猜你喜欢
      • 2020-11-24
      • 1970-01-01
      • 2020-10-27
      • 2014-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-17
      • 1970-01-01
      相关资源
      最近更新 更多