8

I'm attempting to write a unit test for an Oclif hook that contains a simple prompt. I want to test the output of the hook, given a 'Y' or 'N' response to the prompt.

import {Hook} from '@oclif/config'
import cli from 'cli-ux'

const hook: Hook<'init'> = async function () {

  const answer = await cli.prompt("Y or N?")

  if(answer === 'Y') {
    this.log('yes')
  }
  else {
    this.log('no')
  }
}

export default hook

I'm using the 'fancy-test' and '@oclif/test' test frameworks described here: https://oclif.io/docs/testing

I have tried stubbing the prompt and simulating stdin but neither are working - either the stubbed function is not available or the output is an empty string.

Here's an attempt at one test (doesn't work because 'cli.prompt is not a function'):

import {expect, test} from '@oclif/test'
import cli from 'cli-ux'
import * as sinon from 'sinon';

describe('it should test the "configure telemetry" hook', () => {
  test
  .stub(cli, 'prompt', sinon.stub().resolves('Y'))
  .stdout()
  .hook('init')
  .do(output => expect(output.stdout).to.contain('yes'))
  .it()
})

It occurred to me that I'm probably not structuring my test properly. If anyone could point me in the right direction or provide some pseudo / sample code as to how to approach testing the above hook that would be amazing - thanks!

jspru
  • 1,060
  • 1
  • 9
  • 17

1 Answers1

9

Have you tried with:

import {expect, test} from '@oclif/test'
import cli from 'cli-ux'
import * as sinon from 'sinon';

describe('it should test the "configure telemetry" hook', () => {
  test
  .stub(cli, 'prompt', () => async () => 'Y')
  .stdout()
  .hook('init')
  .do(output => expect(output.stdout).to.contain('yes'))
  .it()
})

Stubbing with .stub(cli, 'prompt', () => async () => 'Y') worked for me

st.huber
  • 1,481
  • 2
  • 24
  • 45
  • If you have any pointers about, how we can capture this.warn(message: string | Error) data which continues after giving warning. Thanks In advance – lAH2iV Sep 22 '21 at 17:23
  • 1
    Just from the code snippet it's hard to tell. I kept having problem trying to log in oclif as well. Maybe you can open a separate question about it? – st.huber Sep 23 '21 at 07:23
  • Does it work for multiple prompts? – Souvik De Feb 04 '22 at 13:50
  • You can write a function within `async (input) => { return 'Y'}` and return different values depending on what is prompted for. – st.huber Feb 07 '22 at 09:01