Michael Bush
Michael Bush

Reputation: 1

Testing console output (process.stdout.write) from async functions using Mocha

I'm having issues capturing process.stdout.write within an async function in node.js. I've read a lot of other people's solutions, and am missing something obvious, but I can't figure out what it is. I found solutions here that worked for the sync functions, but can't make the async thing work. I've tried both homegrown solutions, as well as the test-console.js library.

Here's the function I'm trying to test:

const ora = require('ora')

const coinInserted = (totalInserted) => {
  const spinner = ora('    KA-CHUNK').start();
  const output = `Amount Inserted: $${(totalInserted / 100).toFixed(2)}`;
  setTimeout(() => {
    spinner.text = `    ${output}`;
    spinner.color = 'green';
    spinner.succeed();
      process.stdout.write('Please Insert Coins > ');
    }, 500);
};

The docs in the test-console.js library say to test an async function like so:

var inspect = stdout.inspect();
functionUnderTest(function() {
    inspect.restore();
    assert.deepEqual(inspect.output, [ "foo\n" ]);
});

...but I don't understand the syntax here of functionUnderTest. I take it I have to modify the function I'm testing to accept a callback function, inside of which I'll call the test (inspect and assert) functions? But that doesn't seem to work either.

Upvotes: 0

Views: 1206

Answers (1)

deerawan
deerawan

Reputation: 8443

Since you use setTimeout(), we can use sinon.useFakeTimers to emulate the timeout.

Here is the example

const chai = require('chai');
const assert = chai.assert;
const sinon = require('sinon');
const proxyquire = require('proxyquire');

const succeedStub = sinon.stub(); // try to make the expectation this method is called
const index = proxyquire('./src', {
  'ora': (input) => ({ // try to mock `ora` package
    start: () => ({
      text: '',
      color: '',
      succeed: succeedStub
    })
  })
})

describe('some request test', function() {    
  it('responses with success message', function() {    
    const clock = sinon.useFakeTimers(); // define this to emulate setTimeout()

    index.coinInserted(3);
    clock.tick(501); // number must be bigger than setTimeout in source file

    assert(succeedStub.calledOnce); // expect that `spinner.succeed()` is called
  });
})

Ref:

Upvotes: 1

Related Questions