網站搜尋

typescript - 單元測試使用 vscode 擴展 API 函數的函數


我正在嘗試找出一種方法來對函數進行單元測試,這些函數包含了 vscode 擴充功能 API 中的輔助函數,例如 showQuickPick。使用範例:vscode.window.showQuickPick(['one', 'two']);。

我一直在嘗試對那些進行存根和模擬,但雖然我不確定這是否真的正確的方法,無論如何我對此都沒有任何進展。

一個完整的範例可能看起來像這樣:

logic.js

export async function unitTestMe(): Promise<string> {
  const quickPickAnswer: string = vscode.window.showQuickPick(['one', 'two']);
  return quickPickAnswer;
}

logic.test.js

import { unitTestMe } from './logic';
describe('should return user input', () => {
  test('', () => {
     const expected: string = 'expect me';
     const actual: string = await unitTestMe();
     expect(actual).to.eql(expected);
  })
})

答案#1

這是我在目前專案中所做的:我創建了一個名為 VscodeEnvironment 的類,在其中封裝了 VS Code API(作為一個間接層)

export class VscodeEnvironment {
    public getActiveTextEditor(): vscode.TextEditor{
        return vscode.window.activeTextEditor;
    }

    public showErrorMessage(message: string): void {
        vscode.window.showErrorMessage(message);
    }

    public showQuickPick<T extends QuickPickItem>(items: T[] | Thenable<T[]>, options?: QuickPickOptions, token?: CancellationToken): Thenable<T | undefined> {
        return vscode.window.showQuickPick(items, options, token);
    }
}

在我的單元測試中,我設置了一個 VscodeEnvironment 的存根來返回一個已解決的 Promise:

let vscodeEnvStub = moq.Mock.ofType(VscodeEnvironment);
vscodeEnvStub.setup(x => x.showQuickPick(moq.It.isAny(), moq.It.isAny())).returns(()=>Promise.resolve<QuickPickItem>(fakeItem));

我正在使用 typemoq,但在其他模擬框架中應該沒有太大差別

答案#2

你的問題的解決方案被稱為「依賴注入」:

首先,嘗試將依賴項從你的代碼中分離出來,然後以一種可以從函數、類或原型之外設置這些依賴項的方式來進行。

即

 function unitTestMe(vsCodeExtensionApi) {
    const quickPickAnswer = vsCodeExtensionApi.window.showQuickPick(['one', 'two']);
    return quickPickAnswer;
 }

或者如果你有課

class MagicClass {
   constructor(vsCodeExtensionApi) {
      this._vsCodeExtensionApi = vsCodeExtensionApi;
   }

   unitTestMe() {
       const quickPickAnswer = this._vsCodeExtensionApi.window.showQuickPick(['one', 'two']);
       return quickPickAnswer;
   }

現在你可以像這樣將一個存根或模擬傳遞給 unitTestMe

const stub = {
   window : {
      showQuickPick = function(param) {
         // return some stuff
      }
   }
}

unitTestMe(stub)