I am writing Mocha unit tests for Typescript code containing Jquery . I'm using jsdom for getting the document object. When I compile my TS code to JS and run the tests, it throws an error [ReferenceError: $ is not defined] .
My Typescript code is here
export function hello(element) : void {
$(element).toggleClass('abc');
};
My unit test code is as follows:
import {hello} from '../src/dummy';
var expect = require('chai').expect;
var jsdom = require('jsdom');
var document = jsdom.jsdom();
var window = document.defaultView;
var $ = require('jquery')(window);
describe('TEST NAME', () => {
it('should run', (done) => {
hello($('div'));
done();
});
});
When I run Mocha test it shows
<failure message="$ is not defined"><![CDATA[ReferenceError: $ is not defined ...
]]></failure>
Also tried using global.$ = require("jquery"); but does not work.
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;
I found this question in 2020 and Louis got me pointing in the right direction. However, I found jsdom-global
an easier alternative way of getting document working in Mocha. I installed jsdom-global
following the instructions at jsdom-global
I used these lines to get jQuery and $ working as expected:
require('jsdom-global')();
global.window = window;
global.$ = require('jquery');
global.jQuery = $;
Then this test passed with flying colours:
const assert = require("chai").assert;
function test(){
return "test";
}
describe('Setting up global constants...', function () {
describe('Libraries...', function () {
it('jQuery and $ are present', () => {
assert(jQuery !== undefined);
assert($ !== undefined);
assert($ === jQuery);
assert($.isFunction(test));
});
});
});
If you can't or don't want to alter the global namespace type definition, you can still include jQuery, as following:
const globalAny:any = global;
const $ = globalAny.$ = require('jquery')(window);
The full initialization of jQuery then becomes:
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = (new JSDOM());
const globalAny:any = global;
const $ = globalAny.$ = require('jquery')(window);
如上所述,您应该正确导入 jQuery: import $ = require('jquery');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.