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

Я пытаюсь протестировать React-приложение с помощью Jest. Я использую Enzyme shallow для рендеринга моего 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;

а это мой App-test.js:

import React from 'react'
import { shallow } from  'enzyme'
import App from '../components/App.js'

describe( '<App />', () => {
  it('Button disable when input is empty', () => {
    const App = shallow(<App />);

    expect(App.find('.my-button').hasClass('disabled')).to.equal(true);

  });

});

И это ошибка при запуске npm test:

Снимок экрана терминала

Это мой первый раз, когда я тестирую в шутку, пожалуйста, не мог бы кто-нибудь помочь мне с какой-либо идеей об этой ошибке?


person Juan Camilo Hernández Moreno    schedule 30.09.2016    source источник
comment
Можете ли вы отследить, где используется contextType, я не смог найти contextType в вашем фрагменте. Все, что вам нужно сделать, это определить объект, который вызывает contextType.   -  person Thomas John    schedule 03.10.2016


Ответы (5)


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

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

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

//    Use a different name
//    ↓
const app = shallow(<App />);
person sanrodari    schedule 01.10.2016
comment
Всегда полезно использовать const wrapper = shallow(<App />);, поскольку возврат shallow() - это неглубокая оболочка. - person Priya Ranjan Singh; 18.01.2019

Это будет та же ошибка 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

person Ser    schedule 30.11.2016
comment
Это было проблемой для меня. Я случайно импортировал через деструктуризацию, думая, что экспорт был нормальным, а не export default. Пришлось изменить: import { MyComponent } from './index' на: import MyComponent from './index' - person Brendan Moore; 12.01.2017
comment
это идеальный ответ, жаль, что некоторые инструменты синтаксиса / линтинга не могут отловить такого рода ошибки. - person ; 25.04.2017
comment
Спасибо за этот ответ. У меня была та же проблема, что и у @Brendan, и я предполагал export default + import Name вместо фактического export const + import { Name }. - person Trevedhek; 20.08.2017
comment
Когда я преобразовывал компоненты класса в функции с хуками, я забыл экспортировать. Я полагаю, что многие люди могут совершить ту же ошибку. Спасибо. - person Wray Bowling; 21.12.2020

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

Так что вместо:

import { Foo } from './Foo'

использовать:

import Foo from './Foo'

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

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

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

"import/no-unresolved": 1,

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

import {Header} from './Header';

это исправило это

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

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

person stefan    schedule 13.06.2017

В моем случае я импортировал компонент по умолчанию с синтаксисом именованного компонента.

Например, что-то вроде:

import {TestComponent} from "../../components/TestComponent";

вместо того

import TestComponent from "../../components/TestComponent";

Обновление импорта для использования правильного синтаксиса устранило проблему. Хотя глупо.

person Sasi Kumar M    schedule 26.07.2020