Amen Ra
Amen Ra

Reputation: 2851

How to use array prototype some in my Jest test for my React Component?

I am getting the following error when trying to run my test on my React loader component:

TypeError: Cannot read property 'some' of undefined

or

TypeError: error.some is not a function

Here is my component

import React, {
  Component
} from 'react';
import PropTypes from 'prop-types';

import ServiceError from '../ServiceError/ServiceError';
import Spinner from '../Spinner/Spinner';

class Loader extends Component {
  static displayName = 'Loader';

  static propTypes = {
    error: PropTypes.array,
    loaded: PropTypes.bool.isRequired,
    noData: PropTypes.object,
    render: PropTypes.func.isRequired
  };

  get spinner() {
    const {
      loaded
    } = this.props;

    return <Spinner show = {!loaded
    }
    />;
  }

  get component() {
    const {
      loaded,
      noData,
      render
    } = this.props;

    if (!loaded && !this.hasError) {
      return this.spinner;
    }

    if (!loaded && this.hasError) {
      return this.serviceError;
    }

    // Handles API returning no data scenario
    if (loaded && !this.hasError && noData) {
      return this.serviceError;
    }

    return render();
  }

  get hasError() {
    const {
      error
    } = this.props;

    return error.some(el => el.show === true);
  }

  get serviceError() {
    const {
      noData
    } = this.props;

    if (this.hasError) {
      return <ServiceError / > ;
    }

    return <ServiceError { ...noData
    }
    noIcon = {
      true
    }
    />;
  }

  render() {
    return this.component;
  }
}

export default Loader;

And here is the test I wrote

import React from 'react';
import renderer from 'react-test-renderer';

import Loader from './Loader';

describe('<Loader />', () => {
      const renderDiv = () => < div > Successfully loaded! < /div>;
      const props = {
        loaded: false,
        render: renderDiv
      };

      it('renders correctly', () => {
            const component = renderer.create( < Loader { ...props
              }
              />);
              const tree = component.toJSON();

              expect(tree).toMatchSnapshot();
            });

          it('renders content', () => {
              const component = renderer.create( < Loader { ...props
                }
                loaded = {
                  true
                }
                />);
                const tree = component.toJSON();

                expect(tree).toMatchSnapshot();
              });

            it('renders error', () => {
                const error = {
                  show: true,
                  message: 'Service failed. Please try again'
                };
                const component = renderer.create( < Loader { ...props
                  }
                  error = {
                    error
                  }
                  />);
                  const tree = component.toJSON();

                  expect(tree).toMatchSnapshot();
                });

              it('renders multiple children', () => {
                const component = renderer.create( <
                  Loader { ...props
                  } >
                  <
                  p > Loading... < /p> <
                  p > Please wait < /p> <
                  /Loader>
                );
                const tree = component.toJSON();

                expect(tree).toMatchSnapshot();
              });

              it('renders serviceError', () => {
                const component = renderer.create( <
                  Loader { ...props
                  } >
                  <
                  p > Loading... < /p> <
                  p > Please wait < /p> <
                  /Loader>
                );
                const tree = component.toJSON();

                expect(tree).toMatchSnapshot();
              });

              it('renders serviceError if loaded is true but noData was passed', () => {
                const noData = {
                  description: 'No data'
                };
                const error = {
                  show: false
                };

                const component = renderer.create( <
                  Loader { ...props
                  }
                  loaded = {
                    true
                  }
                  noData = {
                    noData
                  }
                  error = {
                    error
                  }
                  />
                );
                const tree = component.toJSON();

                expect(tree).toMatchSnapshot();
              });
            });

I thought changing the assertion would work

it('renders error', () => {
      const error = [{
        show: true,
        message: 'Service failed. Please try again'
      }];
      const component = renderer.create( < Loader { ...props
        }
        error = {
          error
        }
        />);
        const tree = component.toJSON();

        expect(tree).toMatchSnapshot();
      });

But that did not work. What am I doing wrong?

Upvotes: 0

Views: 682

Answers (1)

Matteo Basso
Matteo Basso

Reputation: 2704

In some tests you are not providing the error prop to the component, this means that error might be undefined sometimes. So, you cannot read property .some of undefined...

You can do something like this to test its existance:

get hasError() {
  const {
    error
  } = this.props;

  return Array.isArray(error) && error.some(el => el.show === true);
}

Otherwise, you can just provide a default prop:

static defaultProps = {
  error: []
}

Upvotes: 1

Related Questions