2017-06-27 1 views
0

Ich versuche, eine Async-Funktion in der ComponentDidMount zu testen, nach der Suche, kam ich mit der Testfunktion, aber es scheint nicht funktionieren?Wie testet man eine Async-Funktion im Komponentenlebenszyklus?

referring to this anwser

Wo ist meine Testfunktion falsch?

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: 
     {} 

Antwort

0

Der Unterschied zu der Antwort, die Sie beziehen, ist, dass Ihre API-Aufruffunktion fetchRepos in der Komponente in Ihrem Fall fest codiert ist, während sie in der Antwort als prop empfangen wurde.

Wenn Sie diese Funktionen als Requisiten übergeben, können Sie diese leicht zu Testzwecken, insbesondere für Komponententests, vortäuschen. Wenn Sie einen Integrationstest möchten, den Sie wirklich hier schreiben, dann werden Sie wahrscheinlich Ihre netzwerkbezogenen Aufrufe mit etwas wie fetch-mock für fetch oder moxios (https://github.com/mzabriskie/moxios) verspotten müssen, da Sie Axios verwenden.

Sie definieren die erwartete "Serverantwort" mit der Mock-Bibliothek vor Ihrem Aufruf und führen dann Ihre Assertions durch.

+0

aber nach Refactor mein Code, der Fehler immer noch Popup, gibt es einen anderen möglichen Grund? – Liuuil

+0

Wenn du deinen Code umstrukturiert hast, brauchst du die echte API nicht mehr aufzurufen und eine gespielte Funktion als Prop zu übergeben! – CharlieBrown

Verwandte Themen