I want IntelliJ (or any similar IDE, like WebStorm or VSCode) to give me auto-complete for my fields that I define in my test context in a Mocha.js before() hook. I then want to be able to see the auto-complete documentation of that field in all of my unit tests that use that test context.
Here is an example:
describe('🔥Awesome Test Code🔥', async function()
{
/** A super expensive thing that each unit test needs. **/
class ExpensiveThing { expensive = true; }
/**
* Run this once before the first test in this describe block.
* {@link https://mochajs.org/#hooks Mocha Hooks}
* {@link https://mochajs.org/#global-teardown-fixtures Mocha Test Contexts}
*/
before('the first test', async function()
{
// We can prepare anything we want here and set it on this
// so that each unit test can access it when the unit test runs.
// This is better than initializing it in the describe() block
// because then the code would run when mocha parses the tests
// and it would get executed even if the test is not run.
// https://mochajs.org/#global-teardown-fixtures
this.expensiveThingUsedForTheTests = new ExpensiveThing();
//👆 ⬆️ ⬆️
// ________|__________________________________|________
// !!! I want to define the type of this field here !!!
// ----------------------------------------------------
});
it('should be easy', async function(){
this.expensiveThingUsedForTheTests.expensive = false;
//👆 ⬆️ ⬆️
// ________|___________________________|_________________________
// !!! I want this to give me auto-complete and documentation !!!
// --------------------------------------------------------------
assert.equal(this.expensiveThingUsedForTheTests.expensive, false, 'This was not easy!');
});
});
This is what I see instead, when I push CTRL+Q on the field in IntelliJ IDEA:
The trick is to use the @typedef
JSDoc tag along with the @this
tag on each method that has that test context. You can use the @type
tag to document the this.x field in the before() hook.
The documentation is here:
JSDoc @typedef – To define a name for the test context.
JSDoc @this – To link this to the test contexts up.
JSDoc @type – To document the field on this.x.
This is what I mean:
// Add the @this JSDoc comment to specify what the test context is that we are defining in the before() hook:
/**
* @this ThisTestContext
*/
before('the first test', async function()
{
// Create a definition for our specific test context.
// You can use any name instead of 'ThisTestContext'.
// https://jsdoc.app/tags-typedef
/**
* The context for the awesome unit tests. Use this.x to set the test context.
* <p>
* {@link https://jsdoc.app/tags-typedef JSDoc @typedef}
* {@link https://jsdoc.app/tags-this JSDoc @this}
* {@link https://jsdoc.app/tags-type JSDoc @type}
* {@link https://mochajs.org/#hooks Mocha Hooks}
* {@link https://mochajs.org/#global-teardown-fixtures Mocha Test Contexts}
* @typedef {object} ThisTestContext
*/
// Add the @type JSDoc comment above the field you want to document:
/** {@type ExpensiveThing} The expensive thing that we create once and reuse across tests. **/
this.expensiveThingUsedForTheTests = new ExpensiveThing();
//👆 ⬆️ ⬆️
// ________|__________________________________|___________________________
// !!! You just define this normally, plus a @type JSDoc comment above !!!
// -----------------------------------------------------------------------
});
// Add the @this JSDoc comment to link this to the same test context defined in the before() hook:
/**
* @this ThisTestContext
*/
it('should be easy', async function(){
this.expensiveThingUsedForTheTests.expensive = false;
//👆 ⬆️ ⬆️
// ________|___________________________|____________________
// !!! Now all the auto-complete and documentation works !!!
// ---------------------------------------------------------
assert.equal(this.expensiveThingUsedForTheTests.expensive, false, 'This was much easier!');
});
Now we can see the auto-complete working in IntelliJ: