这个测试
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/