2017-06-27 16 views
0

ComponentDidMountで非同期関数をテストしようとしましたが、検索後にテスト関数が出てきましたが、うまくいかないようですか?私のテスト機能と間違っているコンポーネントのライフサイクルで非同期関数をテストする方法は?

referring to this anwser

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); 
}); 

ログ

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

答えて

0

あなたが指摘している答えとの違いは、API呼び出し関数fetchReposが、回答のpropとして受け取られていたのに対し、ケースのコンポーネントにハードコードされていることです。

小道具としてこれらの機能を渡すことで、テストの目的で、特に単体テスト用に簡単に模擬することができます。実際にここで書いている統合テストが必要な場合は、fetch-mockfetch、またはmoxioshttps://github.com/mzabriskie/moxios)などのネットワーク関連のコールをモチーフにする必要があります。

呼び出し前に模擬ライブラリで期待される "サーバー応答"を定義してから、アサーションを実行します。

+0

しかし、私のコードのリファクタリング後、エラーはまだポップアップ、他の可能性のある理由はありますか? – Liuuil

+0

あなたのコードをリファクタリングした場合、実際のAPIを呼び出す必要はなく、模擬関数を小道具として渡すことができます! – CharlieBrown

関連する問題