0

I try to test a async function in the ComponentDidMount, after searching, I came out with the test function, but it seems not work?

referring to this anwser

Where is wrong with my test function?

api.js

export const fetchPopularRepos = (lang: string) => {
  var encodedURI: string = window.encodeURI(
    "https://api.github.com/search/repositories?q=stars:>1 + language:" +
      lang +
      "&sort=stars&order=desc&type=Repositories"
  );
  return axios.get(encodedURI).then(response => response.data.items);
}; 

User.js

import React from "react";
import { Card } from "antd";
import { fetchPopularRepos } from "./api";

class TestUser extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: "initialize",
      item: {}
    };
  }

  componentDidMount() {
    fetchPopularRepos("all")
      .then(item => {
        this.setState({
          items
        });
      })
      .catch(error => console.log(error))  
  }

  handleClick() {
    this.setState({
      text: "You clicked it"
    });
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick.bind(this)}>{this.state.text}</button>
        <div className="wrapper">
          <Card />
          <Card />
          <Card />
        </div>
      </div>
    );
  }
}

export default TestUser;

User.test.js

import React from "react";
import TestUser from "./User";
import { shallow, mount } from "enzyme";
import renderer from "react-test-renderer";
import { Card } from "antd";


  it("should render right after click the button", async () => {
  const expectedItems = [{ id: 2 }];
  const p = Promise.resolve(expectedItems);
  const fetchPopularRepos = str => p;
  const component = mount(<TestUser />);
  await p;

  expect(component.state().item).toEqual(expectedItems); 
});

log

{ Error: Network Error
          at createError (/Users/next/Documents/react-master/react-ant/node_modules/axios/lib/core/createError.js:16:15)
          at XMLHttpRequest.handleError [as onerror] (/Users/next/Documents/react-master/react-ant/node_modules/axios/lib/adapters/xhr.js:87:14)
          at XMLHttpRequest.callback.(anonymous function) (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:289:32)
          at invokeEventListeners (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:219:27)
          at invokeInlineListeners (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:166:7)
          at EventTargetImpl._dispatch (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:122:7)
          at EventTargetImpl.dispatchEvent (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:87:17)
          at XMLHttpRequest.dispatchEvent (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:61:35)
          at XMLHttpRequest.abort (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:405:16)
          at Object.abort (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:315:13)
          at RequestManager.close (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/living/nodes/Document-impl.js:146:21)
          at Window.close (/Users/next/Documents/react-master/react-ant/node_modules/jsdom/lib/jsdom/browser/Window.js:362:29)
          at JSDOMEnvironment.dispose (/Users/next/Documents/react-master/react-ant/node_modules/jest-environment-jsdom/build/index.js:44:19)
          at Promise.resolve.then (/Users/next/Documents/react-master/react-ant/node_modules/jest-cli/build/runTest.js:102:17)
          at process._tickCallback (internal/process/next_tick.js:103:7)
        config:
         { adapter: [Function: xhrAdapter],
           transformRequest: { '0': [Function: transformRequest] },
           transformResponse: { '0': [Function: transformResponse] },
           timeout: 0,
           xsrfCookieName: 'XSRF-TOKEN',
           xsrfHeaderName: 'X-XSRF-TOKEN',
           maxContentLength: -1,
           validateStatus: [Function: validateStatus],
           headers: { Accept: 'application/json, text/plain, */*' },
           method: 'get',
           url: 'https://api.github.com/search/repositories?q=stars:%3E1%20+%20language:all&sort=stars&order=desc&type=Repositories',
           data: undefined },
        request:
         XMLHttpRequest {
           onabort: null,
           onerror: [Function: handleError],
           onload: null,
           onloadend: null,
           onloadstart: null,
           onprogress: null,
           ontimeout: [Function: handleTimeout],
           upload:
            XMLHttpRequestUpload {
              onabort: null,
              onerror: null,
              onload: null,
              onloadend: null,
              onloadstart: null,
              onprogress: null,
              ontimeout: null,
              _ownerDocument: [Object] },
           onreadystatechange: [Function: handleLoad] },
        response: undefined }

  ● should render right after click the button

    expect(received).toEqual(expected)

    Expected value to equal:
      [{"id": 2}]
    Received:
      {}
Liuuil
  • 1,441
  • 3
  • 16
  • 22

1 Answers1

0

The difference with the answer you are referring is that your API calling function fetchRepos is hardcoded in the component in your case, while it was received as a prop in the answer.

Passing these functions as props allows you to easily mock them for testing purposes, specially for unit testing. In case you want an integration test which is what you are really writing here, then you will probably need to mock your network-related calls with something like fetch-mock for fetch, or moxios(https://github.com/mzabriskie/moxios) since you're using axios.

You define the expected "server response" with the mock library prior to your call, and then do your assertions.

CharlieBrown
  • 4,143
  • 23
  • 24