node.js - 在 Mocha 测试中监听 stdout 时“此套接字已关闭”

标签 node.js mocha.js

这个测试

it.only('should not throw', () => {
    var output = '';

    function callback(data) {
        output += data.toString();
    }

    process.stdout.on('data', callback); // error is thrown at this line
    // ...
    process.stdout.removeListener('data', callback);
})

抛出错误:

Error: This socket is closed                                                                           
    at WriteStream.Socket._writeGeneric (net.js:679:19)                                                
    at WriteStream.Socket._write (net.js:730:8)                                                        
    at doWrite (_stream_writable.js:331:12)                                                            
    at writeOrBuffer (_stream_writable.js:317:5)                                                       
    at WriteStream.Writable.write (_stream_writable.js:243:11)                                         
    at WriteStream.Socket.write (net.js:657:40)                                                        
    at Console.log (console.js:43:16)                                                                  
    at Runner.<anonymous> (node_modules\mocha\lib\reporters\spec.js:80:13)
    at emitTwo (events.js:111:20)                                                                      
    at Runner.emit (events.js:191:7)                                                                   
    at Runner.fail (node_modules\mocha\lib\runner.js:251:8)               
    at Runner.uncaught (node_modules\mocha\lib\runner.js:757:8)           
    at process.uncaught (node_modules\mocha\lib\runner.js:839:10)         
    at emitOne (events.js:96:13)                                                                       
    at process.emit (events.js:188:7)                                                                  
    at process._fatalException (bootstrap_node.js:297:26)                                              

node_modules\mocha\lib\reporters\spec.js:80:13 是这些 Mocha 行:

  runner.on('fail', function(test) {
    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);
  });

它应该使用 spawn 测试输出到 process.stdout 的代码,但我无法进入这部分; process.stdout.on('data', ...) 调用会立即引发错误。

最新的 Mocha (5.2.0) 和默认配置仍然存在问题,使用中的报告器不会影响结果。

发生了什么以及如何监听 process.stdout?如果这是不可能的,那么如何在 Mocha 中测试衍生进程的标准输出?

最佳答案

我无法重现错误:process.stdout.on('data', callback);//在这一行抛出错误。很难说为什么它会为你打破。反正 process.stdout 是一个可写的流,所以不支持 data 事件。另一方面,childProcess.stdout 从父级的角度来看是一个可读的流。

拦截子进程的标准输出最简单的方法是:

const ch = spawn(...)
ch.stdout.on('data', d => ...) // 'd' is a buffer

如果您想针对任意生成进程的标准输出进行测试,恐怕您需要在生成进程时将自定义可写流作为子进程的标准输出传递。流需要基于文件描述符,所以不幸的是,简单的 Duplex 将无法正常工作。

这是一个可能的设置:

process.js

const { spawn } = require('child_process')

module.exports = (outStream) => {
  console.log('PARENT')
  const s = spawn('node', [`${__dirname}/child.js`], { stdio: ['ignore', outStream] })

  return () => {
    console.log('PARENT-DISPOSE')
    s.kill()
  }
}

child.js

process.stdout.write('FROM CHILD')
setTimeout(() => process.stdout.write('FROM CHILD END'), 100)

process.spec.js

const { spawn } = require('child_process')
const fs = require('fs')

const process = require('./process.js')

// path to temporary file
const commF = `${__dirname}/comm`

it('test spawn', (done) => {
  const w = fs.createWriteStream(commF)
  let dispose

  w.on('open', () => {
    dispose = process(w)
  })

  // unfortunately I was not able to make fs.createReadStram to read data in real-time
  // so here we use another subprocess just for that
  let readProcess = spawn('tail', ['-f', commF])

  readProcess.stdout.on('data', x => {
    const d = x && x.toString()
    console.log('TEST', d) // only logs from child are present here
    if (d.startsWith('FROM CHILD END')) {
      w.close()
      fs.unlinkSync(commF)
      dispose()
      readProcess.kill()
      done()
    }
  })
}).timeout(500)

并不是说这是最好的方法:它可以被抽象出来以实现可重用性,并且可以删除 tail 依赖项。

关于node.js - 在 Mocha 测试中监听 stdout 时“此套接字已关闭”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50894056/

相关文章:

javascript - .then() 中的 Promise.reject 返回未定义

javascript - 使用 mocha js 测试依赖于上一个异步函数的异步函数

javascript - 如何检查 check 是否应包含 chai-things 的多个属性?

javascript - 如何从 node.js Express 发送 POST 请求?

javascript - 如何将传递给 Nodejs 的查询字符串转发到通过 res.render 提供服务的页面?

javascript - 数组中每个 Node 的 Node.js 异步 waterfall

javascript - 你如何使用 google maps api 进行 mocha 测试,因为没有 html 来添加 google maps api 需要的脚本标签

javascript - Mocha 使用 for 循环进行数据驱动测试总是运行最后一次迭代

node.js - 在expressJS应用程序中进行身份验证

javascript - 通过字符串检查函数闭包中函数是否存在