TypeError: Невозможно прочитать свойства "contextTypes" из undefined

Я пытаюсь протестировать React-приложение с Jest, я использую Enzyme smallow для рендеринга моего компонента App.js в App-test-js, но я получаю эту ошибку: TypeError: Cannot read property 'contextTypes' of undefined

Это мой App.js:

/* global google */
import React, { Component } from 'react';
import Geosuggest from 'react-geosuggest';
import { getAirQuality } from './Client'
import DataTable from './DataTable'
import Errors from 'react-errors'


class App extends Component {

  .
  .
  .

  render() {
    return (
      <div className="App">
        <form onSubmit={this.searchAirQuality.bind(this)}>
          <Geosuggest
            placeholder="Type a location and press SEARCH button!"
            onSuggestSelect={this.onSuggestSelect.bind(this)}
            initialValue={this.state.place}
            location={new google.maps.LatLng(53.558572, 9.9278215)}
            radius="20"/>
          <button className="my-button" type="submit" disabled={!this.state.place}>Button</button>
        </form>
        <DataTable items={this.state.items} />
        <Errors
          errors={this.state.errors}
          onErrorClose={this.handleErrorClose}
        />
      </div>
    )
  }
}

export default App;

Ответ 1

Проблема заключается в том, что вы переопределяете компонент приложения с результатом неглубокого вызова

//    Redefining
//    ↓
const App = shallow(<App />);

Решение состоит в том, чтобы использовать другое имя:

//    Use a different name
//    ↓
const app = shallow(<App />);

Ответ 2

Это будет та же ошибка TypeError: Cannot read property 'contextTypes' of undefined, когда вы импортируете что-то, что не существует.

Вот пример:
AccountFormComponent.jsx (неправильное имя класса):

export class FoeFormComponent extends React.Component { .... }

AccountFormComponent.test.jsx:

import { shallow } from 'enzyme'
import { expect, assert } from 'chai'
import { AccountFormComponent } from '../../src/components/AccountFormComponent

describe('', function () {
  it('', function () {
    const enzymeWrapper = shallow(<AccountFormComponent {...props} />)
  })  
})  

Просто добавьте в тестовый файл следующее: убедитесь, что компонент существует:

it('should exists', function () {
    assert.isDefined(AccountFormComponent)
})

который печатает AssertionError: expected undefined to not equal undefined вместо

Ответ 3

Как упоминалось в @Ser, проблема импорта. Если вы используете правила eslint, это может дать вам подсказку, если какой-либо импорт может завершиться неудачно.

"import/no-unresolved": 1,

Я получил эту ошибку при попытке импортировать компонент из файла jsx

import {Header} from './Header';

это зафиксировало это

import {Header} from './Header.jsx';

Кроме того, поскольку я использовал webpack, я понял, что должен добавить параметр .jsx в параметр resolve.extensions. Таким образом, я могу игнорировать расширения при импорте.

Ответ 4

В моем случае возникла ошибка при импорте модуля, который имеет только один экспорт по умолчанию, но я использовал один импорт.

Итак, вместо:

import { Foo } from './Foo'

использование:

import Foo from './Foo'

где Foo имеет экспорт по умолчанию:

class Foo extends Component {
  render() {
   return (<div>foo</div>)
  }
}
export default Foo;