开玩笑无法在测试期间读取未定义的属性“默认”

时间:2019-05-23 01:05:55

标签: reactjs jestjs create-react-app

我是测试新手,我通过Create-React-App创建了一个React应用,而我只是在尝试进行测试。

我的测试就这么简单

import React from 'react';
import ReactDOM from 'react-dom';
import { App } from '../containers';

it('renders without crashing', () => {
  const div = document.createElement('div');
  expect(3).toBe(3)
});

我想提到的是,在没有 Import App 的情况下运行它时,它可以成功运行。 但是否则会出现以下错误。

TypeError: Cannot read property 'default' of undefined

  at Object.get [as EmailSender] (src/routes/index.js:65:25)
  at Object.EmailSender (src/index.js:37:22)
  at Object.<anonymous> (src/functions/getSettingsDataFromStore.js:1:1)
  at Object.<anonymous> (src/routes/register/RegisterDescription.js:9:1)
  at Object.<anonymous> (src/routes/index.js:6:1)
  at Object.<anonymous> (src/functions/getAvailableRoutes.js:4:1)
  at Object.<anonymous> (src/components/Navbar.js:4:1)
  at Object.<anonymous> (src/components/index.js:6:1)
  at Object.<anonymous> (src/containers/App.js:4:1)
  at Object.<anonymous> (src/containers/index.js:1:1)
  at Object.<anonymous> (src/tests/App.test.js:3:1)

这是我的package.json文件。

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@fortawesome/fontawesome-svg-core": "^1.2.8",
    "@fortawesome/free-solid-svg-icons": "^5.5.0",
    "@fortawesome/react-fontawesome": "^0.1.3",
    "@material-ui/core": "^3.1.2",
    "axios": "^0.18.0",
    "bootstrap": "^4.3.1",
    "cors": "^2.8.4",
    "dotenv": "^5.0.1",
    "email-validator": "^2.0.4",
    "eosjs": "^16.0.9",
    "google-maps-react": "^2.0.2",
    "history": "^4.7.2",
    "ipfs-http-client": "^28.1.1",
    "jquery": "^3.3.1",
    "jwt-decode": "^2.2.0",
    "node-sass": "^4.9.3",
    "npm": "^6.4.1",
    "nstall": "^0.2.0",
    "object-assign": "^4.1.1",
    "postcss-flexbugs-fixes": "^3.3.0",
    "postcss-loader": "^2.1.6",
    "promise": "^8.0.1",
    "qrcode.react": "^0.8.0",
    "query-string": "^6.1.0",
    "rc-steps": "^3.3.0",
    "rc-time-picker": "^3.3.1",
    "react": "^16.3.2",
    "react-app": "^1.1.2",
    "react-bootstrap-datetimerangepicker-edited": "^2.0.8",
    "react-bootstrap-table": "^4.3.1",
    "react-bootstrap-table-next": "^1.4.1",
    "react-datepicker": "^2.4.0",
    "react-dev-utils": "^5.0.2",
    "react-dnd": "^2.6.0",
    "react-dnd-html5-backend": "^2.6.0",
    "react-dom": "^16.3.2",
    "react-dropdown": "^1.4.2",
    "react-error-overlay": "^4.0.1",
    "react-facebook-login": "^4.1.1",
    "react-google-login": "^5.0.0",
    "react-google-recaptcha": "^1.0.5",
    "react-helmet": "^5.2.0",
    "react-jss": "^8.6.1",
    "react-modal": "^3.6.1",
    "react-password-strength": "^2.4.0",
    "react-redux": "^5.0.7",
    "react-router": "^4.2.0",
    "react-router-dom": "^4.3.1",
    "react-scripts": "3.0.0",
    "react-select": "^1.2.1",
    "react-show-more": "^2.0.0",
    "react-tagsinput": "^3.19.0",
    "react-test-renderer": "^16.8.6",
    "reactstrap": "^6.0.1",
    "sass-loader": "^7.1.0",
    "socket.io": "^2.1.1",
    "style-loader": "^0.21.0",
    "url-loader": "^1.1.1",
    "uuid": "^3.3.2",
    "validator": "^10.7.1",
    "whatwg-fetch": "^2.0.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "fix": "eslint --fix src"
  },
  "jest": {
    "collectCoverageFrom": [
      "src/**/*.{js,jsx}",
      "!**/node_modules/**"
    ]
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "devDependencies": {
    "css-loader": "^2.1.1",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-plugin-import": "^2.11.0",
    "eslint-plugin-node": "^6.0.1",
    "eslint-plugin-promise": "^3.7.0",
    "eslint-plugin-react": "^7.7.0",
    "eslint-plugin-standard": "^3.0.1",
    "img-loader": "^3.0.0",
    "stylelint-config-standard": "^18.2.0"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

我已经花费了8多个小时,却没有找到解决方案。每个想法都会受到欢迎。预先谢谢你。

编辑: 这是routes / index.js

export { default as NoMatch } from './NoMatch';
export { default as Logout } from './Logout';
export { default as Explore } from './Explore';
export { default as Login } from './Login';
export { default as RegisterRequired } from './register/RegisterRequired';
export { default as RegisterDescription } from './register/RegisterDescription';
export { default as RegisterBusinessOffers } from './register/RegisterBusinessOffers';
export { default as RegisterBasicInfos } from './register/RegisterBasicInfos';
export { default as RegisterQuestions } from './register/RegisterQuestions';
export { default as EmailSender } from './register/EmailSender';
export { default as EmailVerification } from './register/EmailVerification';
export { default as VerifyYourAccount } from './register/VerifyYourAccount';
export { default as General } from './settings/General';
export { default as Policy } from './Policy';
export { default as BasicInfos } from './settings/BasicInfos';
export { default as BusinessOffers } from './settings/BusinessOffers';
export { default as Description } from './settings/Description';
export { default as Security } from './settings/Security';
export { default as ForgotYourPassword } from './login/ForgotYourPassword';
export { default as ResetPassword } from './login/ResetPassword';

这是您想要的App.js

import React, { Component } from 'react';
import { Route, Switch } from 'react-router';
import { Helmet } from 'react-helmet';
import {
  Header,
  PrivateRoutes,
  Navbar,
  Footer} from '../components';
import ...

...

class App extends Component {
  static defaultProps = {
    className: 'app container-fluid p-0 row no-gutters d-flex',
  }

  constructor(props, context) {
    super(props, context);

    }


  render() {

    if (!this.state.isVerified)
    {
      return (
          <div className="all_wrapper">

         <Header />
         <div className="wrapper">
         <main className={className}>

          <Helmet titleTemplate="%s | ComeTogether" defaultTitle="ComeTogether" />

          <div className="flex-fill">
            <Navbar/>
            <Scene>
              <Switch location={location}>
                <Route
                    component={General}
                    path="/settings/general"
                    exact
                />
                <Route
                    component= {Security}
                    path="/settings/security"
                    exact
                />
                <Route
                  component={VerifyYourAccount}
                />
              </Switch>
              <Footer />
            </Scene>
          </div>

        </main>
      </div>
          </div>
      );
    }else if((!Auth.getProfile().hasOwnProperty("isVenue") && !Auth.getProfile().hasOwnProperty("isServiceProvider")) || (store.getState().flags.completeProfile === true)){
      return (
                <Switch location={location}>
                  <Route
                    component= {RegisterQuestions}
                    path="/register/questions"
                    exact
                  />
                  <Route
                    component= {RegisterBasicInfos}
                    path="/register/basicinfos"
                    exact
                  />
                  <Route
                    component= {RegisterDescription}
                    path="/register/description"
                    exact
                  />
                  <Route
                    component= {RegisterBusinessOffers}
                    path="/register/businessOffers"
                    exact
                  />
                  <Route
                    component= {RegisterQuestions}
                  />
                </Switch>
              );
    }else {
      return (
      <div className="all_wrapper">
         <Header />
         <div className="wrapper">
           <main className={className}>

            <Helmet titleTemplate="%s | ComeTogether" defaultTitle="ComeTogether" />

            <div className="flex-fill">
              <Navbar/>
              <Scene>
                {getAvailableRoutes(location)}
                <Footer />
              </Scene>
            </div>

        </main>
        </div>
    </div>
      );
    }
  }
}

export default PrivateRoutes(App);

和EmailSender.js文件

import React, {Component} from 'react';
import { Helmet } from 'react-helmet';
import "../../styles/register/emailSenderAndVerification.scss";
import {Link} from "react-router-dom";


class EmailSender extends Component {
    constructor(props) {
        super(props)
        this.state = {
        }
        this.redirect = this.redirect.bind(this);
    }

    redirect(){
      this.props.history.push('./login')
    }


    render() {
      var title = "";
      var helmetTitle ="";
      if(window.location.pathname.toLowerCase() === "/emailsender")
      {
        title = "Email Verification"
        helmetTitle = "Register | ComeTogether"
      }else if(window.location.pathname.toLowerCase() === "/resetpassemail")
      {
        title = "Reset Your Password"
        helmetTitle = "Reset | ComeTogether"
      }
    return(
       <div className="container-fluid" id="registration">
          <Helmet>
           <title>{helmetTitle}</title>
          </Helmet>
        <div className = "logoAndRegisterBtn">
            <Link to="/">
                <div className="registration_logo">
                    <img className="comeTogetherLogoLoginAndRegister" alt="" src="/images/ALL LOGOS CT-04.png" />
                </div>
            </Link>

          <div className="emailSenderContainer">
            <div className="emailSenderLogoContainer">
              <img className="emailSenderLogo" alt="" src="images/CT LOGO TEXT-01-no shadow.png" onClick={this.redirect}/>
            </div>
            <div className="emailSenderMain">
              <div className="emailSenderMsgBoxTitle">
                <span> {title}</span>
              </div>
              <div className="emailSenderMsgBoxContent">
                We have send a confirmation email to your registered email address. <b>{localStorage.getItem("email")}</b>.
                <br/>
                Please follow the instructions in the email to continue.
              </div>

              <div className="emailSenderMsgBoxTip">
                <strong>If you haven't received the email, please try the following: </strong>
                <ul>
                  <li>Make sure the email address you provided is correct.</li>
                  <li>Check your spam or junk mail folders.</li>
                  <li>Make sure your email client is functioning normally.</li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default EmailSender;

1 个答案:

答案 0 :(得分:0)

由于要测试或包括可能包含子组件的组件(../containers/App),建议在单元测试中使用浅层渲染来测试基本渲染。

浅渲染使您可以“深入一层”渲染组件,并断言其渲染方法返回的事实,而不必担心子组件的行为(未实例化或渲染)。这不需要DOM。

要了解更多信息,请在此处查看文档:{​​{3}}

我建议您查看酶:https://reactjs.org/docs/shallow-renderer.html,如果您正在测试诸如渲染,状态,事件监听器之类的React组件,它与Jest完美配合。