【发布时间】:2017-12-04 22:38:58
【问题描述】:
我正在尝试测试一个使用 axios 从外部 API 获取数据的函数。为了使我的测试功能尽可能接近真实情况,我正在查询文件中的模拟数据。 axios 不能从本地文件返回数据,这是一个安全特性。所以我正在尝试的解决方案是在我的测试套件中启动一个简单的服务器,在那里提供文件,然后运行我的测试。
我的测试套件现在看起来像这样:
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');
});
}
我正在测试的函数看起来是这样的(使用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;
}
}
}
这是 Jest 给我的错误消息:
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)```
我对这个问题的最佳猜测是,也许 Jest 不能在节点环境中运行(有什么办法可以弄清楚)?所以也许 Express 服务器根本没有运行。然而,我有点超出我的专业知识,所以这只是一个猜测。有没有人能够对真正发生的事情有所了解?我运行 Express 服务器的想法是一个好主意吗?把它放在测试套件中是个好主意吗?如果其中一个或两个问题的答案都是“否”,那么这里的最佳做法是什么?
【问题讨论】:
-
如果它不在 Node 中运行,Express 本身会报错。
-
旁注:您实际上并没有将回调传递给
listen()。通过一个可能会解决您的问题。 -
我没有通过回调来监听?我认为将
tests()作为第二个参数传递是我的回调。此外,您在下面说使beforeEach()异步并将回调传递给listen()。listen()不应该包含在beforeEach()中吗? -
否;您正在调用
tests()并传递它的返回值(即undefined)。就像任何其他函数调用一样。 -
您应该在
beforeEach()中调用listen()并将来自beforeEach()的done回调传递给它。阅读文档并了解回调的工作原理。
标签: javascript node.js unit-testing express jestjs