Sinon Stub Разное значение возвращается каждый раз - PullRequest
1 голос
/ 20 марта 2019

Я довольно новичок в TypeScript / JavaScript, но у меня есть работающее расширение VScode, которое меня вполне устраивает.Моя проблема с моими тестами Мокко.У меня есть следующая функция

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', 'john@example.com')
  }
  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('example@example.com')
      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()
    })

Я занимался этим уже несколько дней, но я не могу получить каждый вызов с другим значением!

Первый вызов возвращается правильно, но все последующиеЗвони, ничего не возвращай.

Если есть лучший способ сделать это, я более чем счастлив попробовать!

1 Ответ

0 голосов
/ 20 марта 2019

Похоже, вам нужно несколько исправлений для вашего async кода.


Прямо сейчас getInput всегда разрешается до undefined. resolve не определено в предложении then, поэтому 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('example@example.com');
  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();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...