Sinon Stub 每次返回不同的值
Sinon Stub Different Value returned each time
我是 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')
})
我正在尝试测试 return 函数中的数据是否正确。我的测试目前看起来像这样:
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()
})
我已经这样做好几天了,但我无法让每次调用都具有不同的值!
第一次调用 return 正确,但所有后续调用都没有 return 任何东西。
如果有更好的方法,我很乐意尝试!
看来您需要对 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')
}
您正在正确创建模拟,您只需要等待 getPackInfo
返回的 Promise
解决,然后再恢复模拟并结束测试。
现在它正在调用 getPackInfo
,然后立即调用 done
,恢复模拟,并在 getPackInfo
中的任何 async
代码之前结束测试甚至有机会 运行.
解决这个问题的最简单方法是使用 async
测试函数并在 Promise
:
上调用 await
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();
});
我是 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')
})
我正在尝试测试 return 函数中的数据是否正确。我的测试目前看起来像这样:
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()
})
我已经这样做好几天了,但我无法让每次调用都具有不同的值!
第一次调用 return 正确,但所有后续调用都没有 return 任何东西。
如果有更好的方法,我很乐意尝试!
看来您需要对 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')
}
您正在正确创建模拟,您只需要等待 getPackInfo
返回的 Promise
解决,然后再恢复模拟并结束测试。
现在它正在调用 getPackInfo
,然后立即调用 done
,恢复模拟,并在 getPackInfo
中的任何 async
代码之前结束测试甚至有机会 运行.
解决这个问题的最简单方法是使用 async
测试函数并在 Promise
:
await
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();
});