0

I am testing my React app with Jest and Enzyme. For mocking an API call I use Mock Service Worker. My problem is, that I get an error with my current test code, saying "TypeError: Cannot read properties of undefined (reading 'company')".

I will add the code of the connected components below. The structure is the following: I have a "Finder" component which imports and uses a "FinderList" component. This "FinderList" component imports a "FinderCard" component and maps it out.

The API call is in the "Finder" component. I try to test this while mocking the API call with Mock Service Worker.Unfortunately, it gives me an empty array for the "location" prop. I am not sure how to solve this, since I am very new to the topic.

Is it even correct that I am mounting the "Finder" component? Or should I mount "FinderList" instead?

finder.jsx component:

import React, { Component }  from 'react';
import FinderList from './finder-list.component';
import { SearchBar } from './search-bar.component';

class Finder extends Component {
    constructor() {
        super();
        this.state = {
          location: [],
          searchField: ''
        };
      }
    
      componentDidMount() {
        fetch('https://jsonplaceholder.typicode.com/users')
        .then(response => response.json())
        .then(location => this.setState({ location: location}));
      }

      render() {
        const { location, searchField } = this.state;
        const filteredLocation = location.filter(location => location.company.name.toLowerCase().includes(searchField.toLowerCase()))
        
        return (
          <div key="component-wrapper">
          <SearchBar
          placeholder='Search Locations'
          handleChange= {e => this.setState({ searchField: e.target.value})}
          />
          <FinderList className="finder-list" location={filteredLocation} key="finder-list" data-test="finder-list">
          </FinderList>
          </div>
        );
      }
      
    }
  export default Finder;

finder-list.jsx component:

import React from 'react';
import FinderCard from './finder-card.component';

const FinderList = props => {
    return <div className='finder-list' key="finder-list">
        {
          props.location.map(locationentry => 
          <FinderCard key={locationentry.id} locationentry={locationentry}/>)
        }
    </div>;
};

export default FinderList;

finder-card.jsx component:

import React from 'react';
import finderimg from './finderimg.png'

const FinderCard = props => (
    <div className='finder-card-container' data-test="finder-card-container" key="finder-card-container">
        <h4 className="locationtitle" data-test="locationtitle" key="locationtitle">{props.locationentry.company.name}</h4>
        <div className="background" key="background"></div>
        <img className="finderimg" alt="finderimage" src={finderimg} data-test="finderimg" key="finderimg"></img>
        <div className="finderinfo" key="finderinfo">
            <p className="address" data-test="address" key="address">{ props.locationentry.address.street } { props.locationentry.address.suite }</p>
            <p className="tag" data-test="tag" key="tag">Media</p>
        </div>
    </div>
);

export default FinderCard;

finder-test.js:

import {  mount } from 'enzyme';
import React from 'react';
import Finder from './finder.component';
import { findByTestAttr } from '../../../utils/index';
import { rest } from 'msw';
import { setupServer } from 'msw/node';

const locationResponse = rest.get("https://jsonplaceholder.typicode.com/users", 
(req, res, ctx) => {
    return res(ctx.json([{
        location: {
            company: {name: "Name"},
            address: {street: "Street", suite: "12"}
        }
    }]))
});

const handlers = [locationResponse];

const server = new setupServer(...handlers);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());


describe('Finder Component', () => {
    
    describe('Should render correctly', () => {


        it("Should have the correct location name", async () => {
            const wrapper = mount(<Finder/>);
            const locationItem = await findByTestAttr(wrapper, 'finder-list');
            expect(locationItem.props.location.company.name).toEqual("Name");
        })

    });

})
Anne
  • 121
  • 1
  • 7

0 Answers0