How to get extensionContext in vscode extension unit test?

Viewed 987

Currently I am writing unit tests about vscode extension. But some functions are using extensionContext and I can't get extensionContext in unit tests. Any way to get it?

3 Answers

Just came across this question, because I had exactly the same problem.

It looks like you can do the following in a test:

const ext = vscode.extensions.getExtension("publisher.extensionName");

And you can return anything from your activate function, so you could decide to return the extension context (or anything else that you need) there:

export async function activate(
  context: vscode.ExtensionContext
): Promise<vscode.ExtensionContext> {
  // Your activation code...

  return context;
}

And then you can access the context in the test:

const ext = vscode.extensions.getExtension("publisher.extensionName");
const myExtensionContext = await ext.activate();


You find publisher.extensionName information in package.json of the extension:

{
    "publisher": "myself",
    "name": "myextension",
    "displayName": "My Extension",
    "description": "",
    "version": "1.0.0",
  ...

Another idea is to add a command that returns the context:

export function activate(context: vscode.ExtensionContext) {
    context.subscriptions.push(vscode.commands.registerCommand('getContext', () => context));
}

and then get the context by:

const context = await vscode.commands.executeCommand("getContext") as vscode.ExtensionContext;

But be careful not to expose the context in production

This is an answer to an old question, but I've had the same problem and I'm answering it now, so others can see it.

I found this solution in https://github.dev/microsoft/vscode extensions/vscode-api-test/src/extension.ts and extensions/vscode-api-test/src/singlefolder-test/state.test.ts files.

First, the context entered in the activate function must be registered in the global as shown below.

import * as vscode from 'vscode';

export function activate(_context: vscode.ExtensionContext) {
    // Set context as a global as some tests depend on it
    (global as any).testExtensionContext = _context;
}

After that, you can use it as follows in the file to be tested.

import * as assert from 'assert';
import 'mocha';
import { ExtensionContext, extensions } from 'vscode';

suite('vscode API - globalState / workspaceState', () => {

    let extensionContext: ExtensionContext;
    suiteSetup(async () => {
        // Trigger extension activation and grab the context as some tests depend on it
        await extensions.getExtension('vscode.vscode-api-tests')?.activate();
        extensionContext = (global as any).testExtensionContext;
    });

    test('state', async () => {
        // Do some tests here using extensionContext
        }
    });
});

In the signature of the activate function, context is received as a parameter, but I don't know why, but here it can be used without setting context as a parameter. It may be that the corresponding value is entered automatically.

Related