Skip to content

Instantly share code, notes, and snippets.

@bsatrom
Created November 8, 2011 21:56
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bsatrom/1349384 to your computer and use it in GitHub Desktop.
Save bsatrom/1349384 to your computer and use it in GitHub Desktop.
Samples for hooking into STDOUT for unit testing in Node.js
exports = module.exports
exports.setup = (callback) ->
write = process.stdout.write
process.stdout.write = ((stub) ->
(string, encoding, fd) ->
stub.apply process.stdout, arguments
callback string, encoding, fd)(process.stdout.write)
return -> process.stdout.write = write
(function() {
var exports;
exports = module.exports;
exports.setup = function(callback) {
var write;
write = process.stdout.write;
process.stdout.write = (function(stub) {
return function(string, encoding, fd) {
stub.apply(process.stdout, arguments);
return callback(string, encoding, fd);
};
})(process.stdout.write);
return function() {
return process.stdout.write = write;
};
};
}).call(this);
exports = module.exports
# server logic omitted for brevity
exports.listen = (port, host, callback) ->
try
server.listen port, host, callback
util.log "Server listening at http://#{host or "127.0.0.1"}:#{port}/"
catch err
util.log err.message
var exports;
exports = module.exports;
exports.listen = function(port, host, callback) {
try {
server.listen(port, host, callback);
return util.log("Server listening at http://" + (host || "127.0.0.1") + ":" + port + "/");
} catch (err) {
return util.log(err.message);
}
};
server = require '../js/server'
hook = require '../js/hook_stdout'
it 'should close the server after the server has started', ->
server.listen '3001'
unhook = hook.setup((string, encoding, fd) ->
expect(string).toContain 'Server connection closed'
)
server.close()
unhook()
@mklement0
Copy link

Great stuff, thanks for sharing; there are problems, though:

  • hook_stdout.coffee won't compile, because it contains an unexpected indent on the last line
  • hook_stdout.js won't compile, because it is missing two return statements to make it the direct translation of its .coffee source

While your technique works great for writes performed by the process itself, it doesn't for writes from child processes created with spawn and { stdio: 'inherit' }. Any idea how to fix that?

@satazor
Copy link

satazor commented Jan 14, 2016

@mklement0 I'm also looking for solutions to stdio: 'inherit'. Did you find any?

@nmccready
Copy link

@satazor and @mklement0 it is missing a return

var exports = module.exports;

exports.setup = function(callback) {
  var write = process.stdout.write;

  process.stdout.write = (function(stub) {
  //bug fix
   return  function(string, encoding, fd) {
      stub.apply(process.stdout, arguments);
      callback(string, encoding, fd);
    };
  })(process.stdout.write);

  return function() {
    process.stdout.write = write;
  };
};

@elidoran
Copy link

elidoran commented Jan 5, 2017

# this isn't necessary:
# exports = module.exports

exports.setup = (callback) ->
  write = process.stdout.write

  # use `do` to immediately call a function
  process.stdout.write = do (stub = write) ->
    (string, encoding, cb) ->
      stub.apply process.stdout, arguments
      callback string, encoding, cd
  
  # fix the indentation here, add an empty return
  return -> process.stdout.write = write ; return

Alternate version:

exports.setup = (callback) ->

  write = process.stdout.write

  # no need to do the double step above, this works:
  process.stdout.write = (string, encoding, cb) ->
    write.apply process.stdout, arguments
    callback string, encoding, cb

  -> process.stdout.write = write ; return

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment