How to fix "$ is not defined" error when unit testing Jquery with Typescript using Mocha?

jQuery has to be available globally because your script gets it from the global space. If I modify your code so that var $ = require('jquery')(window); is replaced by:

global.$ = require('jquery')(window);

then it works. Note the two calls: 1st to require jquery, then to build it by passing window. You could alternatively do:

global.window = window
global.$ = require('jquery');

If window is available globally, then there is no need to perform the double call as in the first snippet: jQuery just uses the globally available window.

You probably also want to define global.jQuery since some scripts count on its presence.

Here is a full example of a test file that runs:

/// <reference path="../typings/mocha/mocha.d.ts" />
/// <reference path="../typings/chai/chai.d.ts" />
/// <reference path="../typings/jsdom/jsdom.d.ts" />
/// <reference path="./global.d.ts" />

import {hello} from './dummy';

import chai = require('chai');
var expect = chai.expect;
import jsdom = require('jsdom');
var document = jsdom.jsdom("");
var window = document.defaultView;

global.window = window
global.$ = require('jquery');

describe('TEST NAME', () => {

    it('should run', (done) => {
        hello($('div'));
        done();
    });
});

The typings files are obtained the usual way using tsd. The file ./global.d.ts fixes the issue you may get with setting new values on global. It contains:

declare namespace NodeJS {
    interface Global {
      window: any;
      $: any;
    }
}

dummy.js was also modified like this:

declare var $: any;

export function hello(element) : void {
    $(element).toggleClass('abc');
};

You need to include jsdom and jQuery in Node first:

npm install jsdom --save-dev
npm install jquery --save-dev

and then add this lines into your .js file where you are using jQuery

const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = new JSDOM(`...`);
var jQuery = require('jquery')(window);

var example = (function($) {
 .....your jQuery code....
})(jQuery);

module.exports = example;