0

Here is the Component Code where i call API with getAllData method and set data to the state:

class MyComponent extends Component {
 state = {
   allStatus: []
 }
 componentDidMount() {
  this.getAllData();
 }
 getAllData = async() => {
   let res = await apiCalls(`${Config.masterUrl}/ContentState`, 'GET', {}, `/user-data`, false);
   if (res) {
     this.setState({allStatus: res});
   }
  }
}

Here are the Test cases first I call componentDidMount and call method getAllData then mock API with moxios but it doesn't mock the request.

describe('Render MyComponent Component', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = setup(initialState);
    moxios.install();
  });
  afterEach(() => {
    moxios.uninstall();
  })
  
  it("should call getAllData API Success",  async(done) => {
    const responseData = {
      status: 200,
      error: null,
      data: [Array] // for example
    }
    await wrapper.instance().componentDidMount();
    await wrapper.instance().getAllData()
    moxios.wait(function() {
      const request = moxios.requests.mostRecent();
      request.respondWith(responseData)
      expect(wrapper.instance().state.allStatus.length).not.toBe(0)
      done()
    })
  })
})
Lin Du
  • 88,126
  • 95
  • 281
  • 483
Tarun Kumar
  • 140
  • 1
  • 1
  • 9
  • How can the call to `getAllData` ever complete, if you haven't yet configured moxios to respond to the request it's making? Also you shouldn't be calling component methods directly, the call to `componentDidMount` already calls `getAllData`, and `componentDidMount` gets called by React once the component is mounted. – jonrsharpe Jan 13 '21 at 17:08
  • @jonrsharpe can you please add a test? – Tarun Kumar Jan 14 '21 at 04:10

1 Answers1

0
  1. You don't need to call componentDidMount() and getAllData() methods manually.

As of Enzyme v3, the shallow API does call React lifecycle methods such as componentDidMount and componentDidUpdate

  1. You should install moxios firstly, then shallow render the component. Because the mocks should be ready when we shallow render(call componentDidMount and getAllData) the component.

  2. The return value of respondWith method is a promise, you should make sure it's resolved/rejected. So you need to make assertions after the promise is resolved or rejected.

E.g.

MyComponent.tsx:

import axios from 'axios';
import React, { Component } from 'react';

async function apiCalls(url, method) {
  return axios({ url, method }).then((res) => res.data);
}

export class MyComponent extends Component {
  state = {
    allStatus: [],
  };
  componentDidMount() {
    this.getAllData();
  }
  getAllData = async () => {
    let res = await apiCalls(`http://localhost:3000/api/ContentState`, 'GET');
    if (res) {
      this.setState({ allStatus: res });
    }
  };
  render() {
    return <div>MyComponent</div>;
  }
}

MyComponent.test.tsx:

import React from 'react';
import { shallow } from 'enzyme';
import moxios from 'moxios';
import { MyComponent } from './MyComponent';

describe('Render MyComponent Component', () => {
  let wrapper;
  beforeEach(() => {
    moxios.install();
    wrapper = shallow(<MyComponent></MyComponent>);
  });
  afterEach(() => {
    moxios.uninstall();
  });

  it('should call getAllData API Success', (done) => {
    const responseData = {
      status: 200,
      response: [1, 2, 3],
    };
    moxios.wait(function () {
      const request = moxios.requests.mostRecent();
      request.respondWith(responseData).then(() => {
        expect(wrapper.state('allStatus')).toHaveLength(3);
        done();
      });
    });
  });
});

unit test result:

 PASS  examples/65702308/MyComponent.test.tsx (5.34 s)
  Render MyComponent Component
    ✓ should call getAllData API Success (246 ms)

-----------------|---------|----------|---------|---------|-------------------
File             | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------------|---------|----------|---------|---------|-------------------
All files        |     100 |       50 |     100 |     100 |                   
 MyComponent.tsx |     100 |       50 |     100 |     100 | 17                
-----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.505 s
Lin Du
  • 88,126
  • 95
  • 281
  • 483
  • What if in the componentDidMount call multiple API then how do i know which API is testing with your test case. Example my component have 2 API call now: componentDidMount() { this.getAllData(); this.getUserList()} – Tarun Kumar Jan 14 '21 at 12:28