2017-12-04 3 views
1

Axios를 사용하여 외부 API에서 데이터를 가져 오는 함수를 테스트하려고합니다. 내 테스트 기능을 최대한 실제와 가깝게 유지하기 위해 파일에있는 모의 데이터를 쿼리하고 있습니다. Axios는 보안 기능인 로컬 파일에서 데이터를 반환 할 수 없습니다. 그래서 제가 시도하고있는 솔루션은 테스트 스위트에서 간단한 서버를 돌려서 파일을 제공하고 테스트를 실행하는 것입니다.Jest 테스트 스위트에서 Express.js 서버를 만들 수 있습니까?

내 테스트 스위트 지금이 바로 다음과 같습니다

import React from 'react'; 
import {shallow} from 'enzyme'; 
import express from 'express'; 
import { getFeedId, getFeedData, reverseStop } from '../mocks/apiMock'; 

const app = express(); 
const port = 4000; 
app.use(express.static('../mocks/MockData.json')); 
app.listen(port, tests()); 

function tests() { 
    it('returns the expected feed id for a given subway line',() => { 
     expect(getFeedId('L')).toBe(2); 
    }); 

    it('returns json data',() => { 
     expect.assertions(2); 
     return getFeedData('L').then(data => { 
      expect(data).toBeDefined(); 
      expect(data.header.gtfs_realtime_version).toBe('1.0'); 
     }); 
    }); 

    it('returns a stop_id for a given subway line and stop',() => { 
     expect(reverseStop('L', 'Lorimer St')).toBe('L10N'); 
    }); 
} 

기능 I는 다음과 같이 (Axios의이 getFeedData 인 사용을 테스트하고있어, 내가 생각하지 않는 다른 문제를 일으키는 하지만 나는 긍정적이지 않다.) 여기

const axios = require('axios'); 

export function getFeedId (sub) { 
    switch (sub) { 
     case '1': case '2': case '3': case '4': case '5': case '6': case 'S': 
      return 1; 
     case 'A': case 'C': case 'E': 
      return 26; 
     case 'N': case 'Q': case 'R': case 'W': 
      return 16; 
     case 'B': case 'D': case 'F': case 'M': 
      return 21; 
     case 'L': 
      return 2; 
     case 'G': 
      return 31; 
    } 
} 

export function getFeedData (sub) { 
    if (getFeedId(sub) === 2) { 
     return axios.get('http://localhost:4000').then((data) => JSON.parse(data)); 
    } 
} 

export function reverseStop (sub, stop) { 
    const stops = require('../utils/stops'); 
    const stopObjs = stops.filter((item) => item.stop_name == stop && typeof item.stop_id === 'string' && item.stop_id.charAt(0) == sub); 
    for (var i = 0; i < stopObjs.length; i++) { 
     if (stopObjs[i].stop_id.charAt(stopObjs[i].stop_id.length - 1) == 'N') { 
      return stopObjs[i].stop_id; 
     } 
    } 
} 

는 농담이 나에게주는 오류 메시지입니다 :

문제에서 내 추측은 어쩌면 농담이 (노드 환경에서 실행되지 않는다는 것입니다
FAIL src/tests/api.test.js (23.311s) 
    ● returns json data 

Network Error 

    at createError (node_modules/axios/lib/core/createError.js:16:15) 
    at XMLHttpRequest.handleError [as onerror] (node_modules/axios/lib/adapters/xhr.js:87:14) 
    at XMLHttpRequest.callback.(anonymous function) (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:289:32) 
    at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:219:27) 
    at invokeInlineListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:166:7) 
    at EventTargetImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:122:7) 
    at EventTargetImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:87:17) 
    at XMLHttpRequest.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:61:35) 
    at dispatchError (node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:994:9) 
    at validCORSHeaders (node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:1009:7) 
    at receiveResponse (node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:871:12) 
    at Request.client.on.res (node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:691:38) 
    at emitOne (events.js:96:13) 
    at Request.emit (events.js:191:7) 
    at Request.onRequestResponse (node_modules/request/request.js:1074:10) 
    at emitOne (events.js:96:13) 
    at ClientRequest.emit (events.js:191:7) 
    at HTTPParser.parserOnIncomingClient (_http_client.js:522:21) 
    at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23) 
    at Socket.socketOnData (_http_client.js:411:20) 
    at emitOne (events.js:96:13) 
    at Socket.emit (events.js:191:7) 
    at readableAddChunk (_stream_readable.js:178:18) 
    at Socket.Readable.push (_stream_readable.js:136:10) 
    at TCP.onread (net.js:560:20) 

    ● returns json data 

expect.assertions(2) 

Expected two assertions to be called but only received zero assertion calls. 

    at addAssertionErrors (node_modules/jest-jasmine2/build/setup-jest-globals.js:68:21) 
    at process._tickCallback (internal/process/next_tick.js:109:7)``` 

나는 그것을 알아낼 수있는 방법이 아웃)? 아마 Express 서버가 전혀 실행되지 않을 수도 있습니다. 그러나, 나는 약간의 추측을 넘어서도록 전문성을 약간 넘어선 다. 누구든지 실제로 진행되고있는 일에 대해 약간의 빛을 발할 수 있습니까? 익스프레스 서버를 실행하는 것이 좋은 생각입니까? 테스트 스위트에 넣는 것이 좋은 생각 이었습니까? 그 질문들 중 하나 또는 둘 모두에 대한 대답이 "아니오"일 경우 여기에 모범 사례는 무엇입니까?

+0

노드에서 실행되고 있지 않으면 Express 자체에서 오류가 발생합니다. – SLaks

+0

사이드 노트 : 실제로 콜백을 'listen()'에 전달하지 않습니다. 하나를 건네면 문제가 해결 될 수 있습니다. – SLaks

+0

나는 듣기 위해 콜백을 전달하지 않을 것인가? 두 번째 매개 변수로'tests()'를 전달하는 것이 콜백이라고 생각했습니다. 또한, beforeEach()를 비동기로 만들고 콜백을'listen()'에 전달하기 위해 아래에서 설명합니다. 'listen()'은'beforeEach()'에 포함되지 않아야합니까? – bkula

답변

1

각 테스트마다 실행되도록 서버 beforeEach() (afterEach())을 만들어야합니다.

docs.

또한 테스트를 병렬로 실행할 수 있도록 사용하지 않는 포트를 선택해야합니다.

+0

사용하지 않는 포트는 어떻게 선택합니까? Express에서 임의의 포트를 청취해야합니까? 만약 내가 실수하지 않는다면,'app.listen()'을 비워 두는 것입니다. 그래서 콜백을 어떻게 추가할까요? 또한 서버 beforeEach()를 만들면 내 콜백을 변경해야합니까? – bkula

+1

@bkula : '0'을 전달하십시오. https://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback – SLaks

+0

고마워요,하지만 콜백이 어떻게 보이는지 아직도 혼란 스럽습니다. 모든 테스트를 실행하는'app.listen()'콜백을 전달하면'beforeEach()'를 사용하는 목적을 상쇄하지 않습니까? 어떻게해서든지 반복해야합니까? 아니면'beforeEach()'의 코드가 모든 테스트 전에 여전히 실행됩니까? – bkula

관련 문제