Reputation: 2851
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
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