Node.js & Mocha/Should (JavaScript, ES6):代码未执行,但看起来应该执行

Node.js & Mocha/Should (JavaScript, ES6): Code not executed although it looks like it should

我尝试使用 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();

您需要 return 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();
    })
});

请注意,如果超过为 运行 mocha 测试设置的超时,调用 done() 将失败。请参阅此处以了解更多信息 - https://mochajs.org/#timeouts

我怀疑问题出在对 Node.js 的事件循环和 Mocha 使用 promises 而不是旧的 "done" 回调的彻底误解。

以下解决方案对我有用:

'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();