React Native 玩笑不断抛出 -TypeError: Component is not a function 错误

sun*_*nts 5 javascript unit-testing jestjs react-native

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

\n\n

我从 jest 得到的测试结果如下:

\n\n
Using Jest CLI v11.0.2, jasmine2, babel-jest\nRunning 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).\n FAIL  app/views/connections/__tests__/Connections-test.js (3.217s)\nConnections\n  \xe2\x9c\x95 it should return View\n\nConnections \xe2\x80\xba it should return View\n  - TypeError: Component is not a function\n        at ShallowComponentWrapper._constructComponentWithoutOwner (node_modules/react/lib/ReactCompositeComponent.js:250:8)\n        at ShallowComponentWrapper.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:159:15)\n        at ShallowComponentWrapper.wrapper [as mountComponent] (node_modules/react/lib/ReactPerf.js:66:13)\n        at ReactShallowRenderer._render (node_modules/react/lib/ReactTestUtils.js:385:10)\n        at _batchedRender (node_modules/react/lib/ReactTestUtils.js:366:10)\n        at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react/lib/Transaction.js:136:12)\n        at Object.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:63:13)\n        at Object.batchedUpdates (node_modules/react/lib/ReactUpdates.js:97:18)\n        at ReactShallowRenderer.render (node_modules/react/lib/ReactTestUtils.js:359:14)\n        at renderConnections (app/views/connections/__tests__/Connections-test.js:17:10)\n        at Object.eval (app/views/connections/__tests__/Connections-test.js:25:12)\n1 test failed, 0 tests passed (1 total in 1 test suite, run time 9.326s)\n--------------------|----------|----------|----------|----------|----------------|\nFile                |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |\n--------------------|----------|----------|----------|----------|----------------|\n __mocks__/         |    78.33 |    48.15 |    46.15 |      100 |                |\n  react-native.js   |    78.33 |    48.15 |    46.15 |      100 |                |\n views/connections/ |    88.89 |       75 |       50 |       80 |                |\n  Connections.js    |    88.89 |       75 |       50 |       80 |              9 |\n--------------------|----------|----------|----------|----------|----------------|\nAll files           |    79.71 |    51.61 |    46.67 |    96.15 |                |\n--------------------|----------|----------|----------|----------|----------------|\n
Run Code Online (Sandbox Code Playgroud)\n\n

我要测试的组件如下所示:

\n\n
import React, { PropTypes } from \'react\';\nimport {\n  View,\n  Text,\n} from \'react-native\';\n\nconst Connections = React.createClass({\n  render () {\n    return (\n      <View>\n        <Text>\n          Connections Page\n        </Text>\n      </View>\n    )\n  }\n})\n\nexport default Connections\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的 package.json 如下所示:

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

最后我的示例测试用例如下:

\n\n
jest.autoMockOff();\n\nimport React, { View } from \'react-native\';\nimport utils from \'react-addons-test-utils\';\n// import React, {View} from \'react-native\';\n// import utils from \'react-addons-test-utils\';\n\njest.dontMock(\'../Connections\');\n// import Connections from \'../Connections\';\nconst Connections = require(\'../Connections\');\n\ndescribe(\'Connections\', (props) => {\n  function renderConnections() {\n    const renderer = utils.createRenderer();\n    renderer.render(<Connections {...props}/>);\n    const output = renderer.getRenderOutput();\n    return {\n      props,\n      output,\n      renderer\n    };\n  }\n  it(\'should return View\', () => {\n    const output = renderConnections({someProps: true});\n    expect(output).toEqual(View);\n  })\n})\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
\'use strict\';\n/**\n * ## Imports\n *\n * ReactNative is actually React\n */\nconst React = require(\'react\');\nconst ReactNative = React;\n\n/**\n * ## These need additional mocking\n *\n * ReactNative is actually React\n */\nReactNative.StyleSheet = {\n    create: function create(styles) {\n        return styles;\n    }\n};\nclass View extends React.Component {\n    render() { return false; }\n}\nclass PixelRatio extends React.Component {\n    static get() { return 1; }\n}\n/**\n * ## Stubs\n *\n * Simple replacements for testing\n */\nReactNative.View = View;\nReactNative.ScrollView = View;\nReactNative.Text = View;\nReactNative.TouchableOpacity = View;\nReactNative.TouchableHighlight = View;\nReactNative.TouchableWithoutFeedback = View;\nReactNative.ToolbarAndroid = View;\nReactNative.Image = View;\nReactNative.PixelRatio = PixelRatio;\nReactNative.NativeModules= {};\n\nReactNative.Platform = {};\nmodule.exports = ReactNative;\n
Run Code Online (Sandbox Code Playgroud)\n

msa*_*dak 6

重新启动 Metro 捆绑程序yarn startnpm start解决了我的问题


Jea*_*ser 0

我猜你在测试中的导入:

jest.autoMockOff();

import React, { View } from 'react-native';
Run Code Online (Sandbox Code Playgroud)

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

您想使用相对./react-native导入吗?

  • 感谢回复。我终于发现解决方案是我必须在测试文件上使用 `jest.unmock('../Connections')` 而不是 `jest.dontMock('../Connections');` 。Jest的官方文档中关于jest.unmock的说法是这样的: **注意:这个方法之前被称为dontMock。使用 babel-jest 时,对 unmock 的调用将自动提升到代码块的顶部。如果你想明确避免这种行为,请使用 dontMock。** 因此,在我将其更改为 unmock 后,一切正常。 (2认同)