TypeError: Cannot read property 'contextTypes' of undefined

I'm trying to test a React-app with Jest. I use Enzyme's shallow to render my App.js component in App-test-js but I'm getting this error: TypeError: Cannot read property 'contextTypes' of undefined

This is my 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;

and this is my 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);

  });

});

And this the error when I run npm test:

Terminal screenshot

This is my first time with testing in jest, please could someone help me with any idea about this error?

Upvotes: 37

Views: 37552

Answers (5)

Ser
Ser

Reputation: 2870

This would be the same error TypeError: Cannot read property 'contextTypes' of undefined when you are importing something that does not exist.

Here is an example:
AccountFormComponent.jsx (incorrect class name):

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} />);
  });
});

Just add the following to your test file to be sure the component exists:

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

which prints AssertionError: expected undefined to not equal undefined instead

Upvotes: 44

Sasi Kumar M
Sasi Kumar M

Reputation: 2630

In my case I was importing a default component with named component syntax.

For example, something like:

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

instead of

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

Updating the import to use the right syntax fixed the issue. Silly one though.

Upvotes: 4

Laszlo
Laszlo

Reputation: 2313

In my case the error occurred when imported a module that has only one default export, but I was using single import.

So instead of:

import { Foo } from './Foo'

use:

import Foo from './Foo'

where Foo has default export:

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

Upvotes: 24

stefan
stefan

Reputation: 2785

As @Ser mentioned could be a import issue. If you are using eslint rules this could give you a hint if any of the imports might fail

"import/no-unresolved": 1,

I got that error on trying to import a component from a jsx file

import {Header} from './Header';

this fixed it

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

Also because I used webpack I realised that I should have added '.jsx' to resolve.extensions option. This way I can ignore the extensions when importing.

Upvotes: 3

sanrodari
sanrodari

Reputation: 1632

The problem here is that you are redefining the the app component with the result of the shallow call

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

The solution would be to use a different name:

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

Upvotes: 35

Related Questions