Testing a React Hooks component with Jest / Enzyme & Axios

Viewed 408

I have a react component that uses Axios to fetch data that is HomePage.js and Post.js to render it on the screen. I'm trying to write test cases for both of them. But everytime i try its failing could someone help me understand what i'm doing wrong in the test cases. Thanks

I'm new to testing and I know for the testing of components Any advice would be appreciated!

HomePage.js

import React, { useState, useEffect } from 'react'; 
import Post from '../../Components/Post/Post';
import axios from 'axios';

const HomePage = () => {

    const [posts, setPosts] = useState('');
    
    const url = 'https://jsonplaceholder.typicode.com/posts/1/comments';

    useEffect( () => {
        AllPosts();
    }, []);

    const AllPosts = () => {
        axios.get(`${url}`)
        .then((response) => {
            const allPosts = response.data;
            setPosts(allPosts);
        })
        .catch( error => console.error(`Error: ${error}`));
    }
    return (
        <div >
            <Post className ="Posts" posts = {posts}/>
        </div>
    )
}

export default HomePage;


HomePage.test.js

import React from 'react';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Post from './Post';

configure ({adapter: new Adapter()});

describe('<Post />', () => {
    it('Should render all the posts ', () => {
        const wrapper = shallow(<Post />);
        expect (wrapper.length).toBe(1);
    });
});

Post.js

import React from 'react';
import './Post.css';

const Post = (props) => {

    const displayPosts = (props) => {
    const  { posts } = props;

    if ( posts.length > 0) {
        return(
            posts.map( (post) => {
                return(
                    <div className ="Post" >
                        <p><b>Name :</b> {post.name}</p>
                    <div className = "Info">
                        <div className = "email"> <b>Email :</b> {post.email}</div>
                        <div className = "body"> <b>Body :</b>{post.body}</div>
                    </div>
                    
                </div>
                )
            })
        )
    } 
}
    return (
        <div className = "Posts">
            { displayPosts(props) }
        </div>
    )
}

export default Post;

Post.test.js

import React from 'react';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Post from './Post';

configure ({adapter: new Adapter()});

describe('<Post />', () => {
    it('Should render all the posts ', () => {
        const wrapper = shallow(<Post />);
        expect (wrapper.find(Email)).toHaveLength(3);
    });
});
1 Answers

i tried using mount and mocking get method not working as expected to get 100% coverage,

export default function HomePage (){}

it('axios mock', async () => {
    let wrapper;
    
    axios.get = jest.fn()
    jest.mock('Axios');

    const data = [
        {
          "userId": 1,
          "id": 1,
          "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
          "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
        }
      ]
    
      await act(async ()=> {
        await axios.get.mockImplementationOnce(()=> Promise.resolve(data))
        wrapper = mount(<HomePage />)
      })
    
    await expect(axios.get).toHaveBeenCalledTimes(1);
    wrapper.update();
    await expect(axios.get).toHaveBeenCalledWith('https://jsonplaceholder.typicode.com/posts?_limit=5')
    await expect(wrapper.find("Post").at(0)).toHaveLength(1)
    expect(toJson(wrapper)).toMatchSnapshot();
  
  })
Related