简体   繁体   English

Node.js和Mocha / Should(JavaScript,ES6):虽然看起来应该像代码那样未执行

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

I trying to write some test code in a nodejs project using mocha/should and request. 我试图使用mocha / should和request在nodejs项目中编写一些测试代码。

My code initializes an array with some web addresses in order to send a GET request to a remote server and check the content of the responses. 我的代码使用一些网址初始化了一个数组,以便将GET请求发送到远程服务器并检查响应的内容。

My mock-up right now just needs to print out the response however for some reason the flow never gets there. 我现在的模型只需要打印出响应,但是由于某种原因,流程永远不会到达那里。

Note that I have a for loop. 请注意,我有一个for循环。 Inside the loop the first console log prints stuff out, however for some reason the rest of the code inside that loop is being skipped. 在循环内,第一个控制台日志将输出内容,但是由于某种原因,该循环内的其余代码将被跳过。 I put break points in debug mode but my code only reaches the first console.log() inside the loop and the request part is skipped. 我将断点置于调试模式,但是我的代码仅到达循环内的第一个console.log(),并且跳过了请求部分。

I tried to use also the unpromisified version of request (streams and all) but I get the same problem - the code never reached that request line so of course it doesn't go any further to printing anything inside. 我也尝试使用请求的未承诺版本(流和全部),但是我遇到了同样的问题-代码从未到达请求行,因此当然不会进一步打印内部任何内容。

Is it something to do with asynchronous work inside nodejs? 这与Node.js内部的异步工作有关吗? something else? 还有什么吗

What am I missing? 我想念什么?

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

You need to either return a Promise or call the done() callback after running async tests. 您需要在运行异步测试后返回Promise或调用done()回调。 Since you are running async requests in a loop you need to accumulate the request promises in an array and use Promise.all() 由于您正在循环中运行异步请求,因此您需要在数组中累积请求承诺并使用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);
});

If you want to use done() you can do the following - 如果要使用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();
    })
});

Note that, calling done() will fail if it exceeds the timeout set for running mocha tests. 请注意,如果调用done()超过为运行Mocha测试设置的超时时间,则将失败。 See here to learn more - https://mochajs.org/#timeouts 请参阅此处以了解更多信息-https://mochajs.org/#timeouts

As I suspected the problem was with misunderstanding thoroughly Node.js's event loop and Mocha's work with promises instead of the older "done" callbacks. 我怀疑问题出在彻底误解了Node.js的事件循环和Mocha的诺言,而不是旧的“完成”回调。

The following solution worked for me: 以下解决方案为我工作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM