每次返回Sinon Stub Different Value

问题描述 投票:1回答:1

我是TypeScript / JavaScript的新手,但我有一个工作的VScode扩展,我很满意。我的问题是我的Mocha测试。我有以下功能

export async function getPackInfo (): Promise<IPackInfo> {
  let validChars = '^[0-9a-zA-Z-]+$'
  let ref
  ref = await getInput('Pack Reference (lowercase and (-) only)', 'pack-reference', 'my-first-pack')
  if (!ref.match(validChars)) {
    vscode.window.showErrorMessage('Pack name can only contain letters, numbers and dashes', 'Got it')
    return Promise.reject(new Error('Pack name can only contain letters, numbers and dashes. Pack will not be created correctly.'))
  }
  console.log(ref)
  let packname = ref.replace(/-/g, ' ').toLowerCase()
  .split(' ')
  .map((s) => s.charAt(0).toUpperCase() + s.substring(1))
  .join(' ')
  console.log(packname)
  let author
  if (getSetting('defaultAuthor')) {
    console.log('Got setting')
    author = getSetting('defaultAuthor')
  } else {
    console.log('Need input')
    author = await getInput('Pack Author', 'Pack Author', 'John Doe')
  }
  console.log(author)

  let email
  if (getSetting('defaultEmail')) {
    email = getSetting('defaultEmail')
  } else {
    email = await getInput('Author Email', 'Author Email', '[email protected]')
  }
  console.log(email)
  if (!author || !email) {
    throw new Error('Pack author or email not defined')
  }
  // Write Pack Config File
  let data: IPackInfo = {
    'ref': ref,
    'packname': packname,
    'author': author,
    'email': email
  }
  return data
}

这个函数调用另一个名为getInput的函数调用vscode.window.showInputBox:

export async function getInput (prompt: string, placeholder: string, defaultValue: string): Promise<string> {
  let value = await vscode.window.showInputBox({ prompt: prompt, placeHolder: placeholder, value: defaultValue }).then(function(value) {
    if (value) {
      resolve(value)
    }
    throw new Error('No value for prompt')
  })

我试图测试数据在'getPackInfo'函数中正确返回。我的测试目前看起来像这样:

    it('Check that packname is converted correctly', function (done) {
      let mockGetInput
      mockGetInput = sinon.stub(vscode.window, 'showInputBox')
      mockGetInput.onFirstCall().resolves('ref-pack-here')
      mockGetInput.onSecondCall().resolves('Test Author')
      mockGetInput.onThirdCall().resolves('[email protected]')
      getPackInfo().then((res) => {
        let output = res['ref']
        console.log(`Output: ${res['packname']}`)
        console.log(`Output: ${res['author']}`)
        console.log(`Output: ${res['email']}`)
        console.log(`Output: ${res['ref']}`)
      }).catch(error => {
        console.log(error)
      })
      done()
      mockGetInput.restore()
    })

我现在已经在这几天,但我无法让每个电话成为不同的价值!

第一个调用正确返回,但所有后续调用都不返回任何内容。

如果有更好的方法,我很乐意尝试!

javascript typescript mocha sinon
1个回答
0
投票

看起来您需要对async代码进行一些修复。


现在getInput总是解决undefinedresolvethen条款中未定义,因此Promise总是拒绝错误,但即使该问题不存在,否则将从value返回的vscode.window.showInputBox永远不会返回。

您可以通过将其更改为此问题来解决这些问题:

export async function getInput (prompt: string, placeholder: string, defaultValue: string): Promise<string> {
  const value = await vscode.window.showInputBox({ prompt: prompt, placeHolder: placeholder, value: defaultValue });
  if (value) {
    return value;
  }
  throw new Error('No value for prompt')
}

你正确地创建了模拟,你只需要等待Promise返回的getPackInfo来解决,然后恢复模拟并结束测试。

现在它正在调用getPackInfo,然后立即调用done,恢复模拟,并在async中的任何getPackInfo代码甚至有机会运行之前结束测试。

解决这个问题的最简单方法是使用async测试函数并在await上调用Promise

it('Check that packname is converted correctly', async () => {  // async test function
  let mockGetInput;
  mockGetInput = sinon.stub(vscode.window, 'showInputBox');
  mockGetInput.onFirstCall().resolves('ref-pack-here');
  mockGetInput.onSecondCall().resolves('Test Author');
  mockGetInput.onThirdCall().resolves('[email protected]');
  const res = await getPackInfo();  // await the Promise
  console.log(`Output: ${res['packname']}`);
  console.log(`Output: ${res['author']}`);
  console.log(`Output: ${res['email']}`);
  console.log(`Output: ${res['ref']}`);
  mockGetInput.restore();
});
© www.soinside.com 2019 - 2024. All rights reserved.