我试图使用 mocha/should 和请求在 nodejs 项目中编写一些测试代码。
我的代码使用一些网址初始化一个数组,以便向远程服务器发送 GET 请求并检查响应的内容。
我现在的模型只需要打印出响应,但是由于某种原因,流程永远不会到达那里。
请注意,我有一个 for 循环。在循环中,第一个控制台日志会打印出内容,但是由于某种原因,该循环中的其余代码被跳过。我将断点置于调试模式,但我的代码只到达循环内的第一个 console.log((,并且跳过了请求部分。
我也尝试使用请求的未承诺版本(流和所有(,但我遇到了同样的问题 - 代码从未到达该请求行,所以当然它不会进一步打印任何内容。
它与nodejs中的异步工作有关吗?别的什么?
我错过了什么?
'use strict';
const Promise = require('bluebird')
, _ = require('underscore')
, should = require('should')
, r = require('request')
, request = Promise.promisifyAll(r.defaults({jar: true}))
, client = require('../whatever/someClient')
, testConfig = require('../config/test-config')
;
Promise.longStackTraces();
class someFeatureTestSet {
constructor() {
//...
this.client = client.getUser();
//...
}
static create() { return new someFeatureTestSet(); }
//... some other consts and functions
initURLs(someUrlParamVal) {
return Array
.apply(null, Array(someUrlParamVal))
.map((x, idx) =>
`http://example.com/whatever?c=${someUrlParamVal}`
);
}
runTests() {
const client = this.client;
const someFeatureTestSet = this;
describe('get stuff', () => {
it('should bla', () => {
const productsLinks = this.initURLs('123');
for (let x in productsLinks) {
console.log(productsLinks[x]); //gets printed, no problem
request.getAsync({ uri: productsLinks[x] })
.then(res => { //code never gets here. why?
console.log(res); //code never gets here. why?
})
}
});
} );
}
}
module.exports = someFeatureTestSet;
const createTestSet = () => someFeatureTestSet.create();
createTestSet().client().runTests();
您需要在运行异步测试后返回 Promise 或调用done()
回调。由于您在循环中运行异步请求,因此您需要在数组中累积请求承诺并使用Promise.all()
it('should bla', () => {
const productsLinks = this.initURLs('123');
let requests = [];
for (let x in productsLinks) {
console.log(productsLinks[x]); //gets printed, no problem
requests.push(request.getAsync({ uri: productsLinks[x] }));
}
return Promise.all(requests);
});
如果要使用done()
可以执行以下操作 -
it('should bla', (done) => {
const productsLinks = this.initURLs('123');
let requests = [];
for (let x in productsLinks) {
console.log(productsLinks[x]); //gets printed, no problem
requests.push(request.getAsync({ uri: productsLinks[x] }));
}
Promise
.all(requests)
.then(() => {
done();
})
});
请注意,如果调用done()
超过为运行 mocha 测试设置的超时,它将失败。请参阅此处以了解更多信息 - https://mochajs.org/#timeouts
正如我怀疑的那样,问题在于彻底误解了 Node.js 的事件循环和 Mocha 使用承诺而不是旧的"完成"回调。
以下解决方案对我有用:
'use strict';
const Promise = require('bluebird')
, _ = require('underscore')
, should = require('should')
, r = require('request')
, request = Promise.promisifyAll(r.defaults({jar: true}))
, client = require('../whatever/someClient')
, testConfig = require('../config/test-config')
;
Promise.longStackTraces();
class someFeatureTestSet {
constructor() {
//...
this.client = client.getUser();
//...
}
static create() { return new someFeatureTestSet(); }
//... some other consts and functions
initURLs(someUrlParamVal) {
return Array
.apply(null, Array(someUrlParamVal))
.map((x, idx) =>
`http://example.com/whatever?c=${someUrlParamVal}`
);
}
runTests() {
const client = this.client;
const someFeatureTestSet = this;
describe('get stuff', () => {
it('should bla', () => {
const productsLinks = this.initURLs('123');
return Promise.map(productsLinks, productsLink =>
return request.getAsync({uri: productsLink })
.then(res => { console.log(res) });
);
});
} );
}
}
module.exports = someFeatureTestSet;
const createTestSet = () => someFeatureTestSet.create();
createTestSet().client().runTests();