3
votes

I'm trying to setup testing on a new project created with react-create-app. Which now seems to be using React 16 and Jest 3 (which supposedly had some breaking changes, or maybe that was enzime). I'm getting an error similar to this post TypeError: dispatch is not a function when I try to test a method using JEST

TypeError: dispatch is not a function at App.componentDidMount (src/components/App.js:21:68)

import React from 'react';
import { Provider } from 'react-redux';
import { mount } from 'enzyme';

import { App } from '../components/App';
import configureStore from '../state/store/configureStore';

window.store = configureStore({
  slider: {
    mainImageIndex: 0,
    pageNum: 1,
    perPage: 4,
  },
});

const appTest = (
  <Provider store={window.store}>
    <App />
  </Provider>
);

describe('App', () => {
  it('should render without crashing', () => {
    mount(appTest);
  });
});

Originally I just tried to do this:

import React from 'react';
import { mount } from 'enzyme';

import { App } from '../components/App';


describe('App', () => {
  it('should render without crashing', () => {
    mount(<App />);
  });
});

Which threw this error

Invariant Violation: Could not find "store" in either the context or props of "Connect(Form(SearchForm))". Either wrap the root component in a , or explicitly pass "store" as a prop

Code for App.js:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { searchPhotos } from '../state/actions/searchPhotos';
import { setMainImageIndex, setFirstPage } from '../state/actions/slider';
import Slider from './Slider';
import SearchForm from './SearchForm';
import Error from './Error';
import '../styles/App.css';

export class App extends Component {
  componentDidMount() {
    const { dispatch } = this.props;
    dispatch(searchPhotos(window.store));
  }

  searchPhotosSubmit = () => {
    const { dispatch } = this.props;
    dispatch(setFirstPage());
    dispatch(setMainImageIndex(0));
    dispatch(searchPhotos(window.store));
  }

  render() {
    const { fetchError } = this.props;
    return (
      <div className="App">
        <header className="App-header">
          <h1 className="App-title">Flickr Slider in React.js</h1>
          <SearchForm onSubmit={this.searchPhotosSubmit} />
        </header>
        {!fetchError ? <Slider /> : <Error />}
      </div>
    );
  }
}

export default connect(state => ({
  fetchError: state.fetchError,
  form: state.form,
  slider: state.slider,
}))(App);
1
can you include App component code?Bartek Fryzowicz
@BartekFryzowicz thanks for looking, App code added above. The rest of the code is here: github.com/pixelwiz/reactjs-flickr-slider-searchpixelwiz

1 Answers

3
votes

Please not that you export both presentational component (as named export) and container component (as default export) in App.js. Then in your tests you import and use the presentational component using:

import { App } from '../components/App';

but you should import connected container component instead using:

 import App from '../components/App'; // IMPORTANT! - no braces around `App`

Since you're using component that is not connected to Redux store dispatch prop is not injected as prop. Just use correct import and it should work.
For more details about importing default and named exports please check this doc. About presentational and container components you can read here.