Unit test functions that use vscode extension api functions

霸气de小男生 提交于 2019-12-11 06:51:56

问题


I am trying to figure out a way to unit test functions, which include helper functions included in the vscode extension api, such as showQuickPick. Example usage: vscode.window.showQuickPick(['one', 'two']);.

I have been trying to stub and mock those, but while I am not sure if that's even the right way to go, I haven't had any luck with it anyway.

A complete example could look something like:

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:


The solution to your problem is called "dependency injection":

At first, try to separate dependencies from your code and then do it in a way that you can set these dependendies from outside of your function or class or prototype.

i.e.

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

or if you have a class

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

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

Now you can pass a stub or mock to unitTestMe like

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

unitTestMe(stub)



回答2:


Here is how I did it in my current project: I created a class called VscodeEnvironment where I wrapped Vs Code API (A layer of indirection)

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);
    }
}

In my unit tests, I set up a VscodeEnvironment stub to return a resolved promise:

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

I'm using typemoq, but it should not be very different in other mocking frameworks




回答3:


If you need to mock the showQuickPick method, the following code will do so:

vscode.window.showQuickPick = (items: string[] | Thenable<string[]>) => {
  return Promise.resolve('Continue') as Thenable<any>;
};


来源:https://stackoverflow.com/questions/47906194/unit-test-functions-that-use-vscode-extension-api-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!