使用 Mocha 使用 Typescript 进行单元测试 Jquery 时如何修复“$ is not defined”错误?
How to fix "$ is not defined" error when unit testing Jquery with Typescript using Mocha?
我正在为包含 Jquery 的 Typescript 代码编写 Mocha 单元测试.我正在使用 jsdom 来获取文档对象。当我将我的 TS 代码编译为 JS 并 运行 测试时,它会抛出错误 [ReferenceError: $ is not defined].
我的 Typescript 代码在这里
export function hello(element) : void {
$(element).toggleClass('abc');
};
我的单元测试代码如下:
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();
});
});
当我 运行 Mocha 测试时它显示
<failure message="$ is not defined"><![CDATA[ReferenceError: $ is not defined ...
]]></failure>
也尝试使用 global.$ = require("jquery"); 但没有用。
如上所述,您应该正确导入 jQuery:import $ = require('jquery');
jQuery 必须全局可用,因为您的脚本从全局 space 获取它。如果我修改您的代码,将 var $ = require('jquery')(window);
替换为:
global.$ = require('jquery')(window);
然后就可以了。注意这两个调用:第一个要求 jquery
,然后通过传递 window
来构建它。您也可以这样做:
global.window = window
global.$ = require('jquery');
如果 window
全局可用,则无需执行第一个代码段中的双重调用:jQuery 仅使用全局可用的 window
.
您可能还想定义 global.jQuery
,因为某些脚本依赖于它的存在。
这是运行的测试文件的完整示例:
/// <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();
});
});
typings
文件是使用 tsd
的通常方式获得的。文件 ./global.d.ts
修复了在 global
上设置新值时可能遇到的问题。它包含:
declare namespace NodeJS {
interface Global {
window: any;
$: any;
}
}
dummy.js
也被修改成这样:
declare var $: any;
export function hello(element) : void {
$(element).toggleClass('abc');
};
您需要先在 Node 中包含 jsdom 和 jQuery:
npm install jsdom --save-dev
npm install jquery --save-dev
然后将此行添加到您使用 jQuery
的 .js 文件中
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;
如果您不能或不想更改全局命名空间类型定义,您仍然可以包含 jQuery,如下所示:
const globalAny:any = global;
const $ = globalAny.$ = require('jquery')(window);
jQuery 的完整初始化变为:
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = (new JSDOM());
const globalAny:any = global;
const $ = globalAny.$ = require('jquery')(window);
我在 2020 年发现了这个问题,路易斯让我指出了正确的方向。但是,我发现 jsdom-global
一种更简单的替代方法,可以让文档在 Mocha 中工作。
我按照 jsdom-global
中的说明安装了 jsdom-global
我使用这些行让 jQuery 和 $ 按预期工作:
require('jsdom-global')();
global.window = window;
global.$ = require('jquery');
global.jQuery = $;
那么这个测试就顺利通过了:
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));
});
});
});
我正在为包含 Jquery 的 Typescript 代码编写 Mocha 单元测试.我正在使用 jsdom 来获取文档对象。当我将我的 TS 代码编译为 JS 并 运行 测试时,它会抛出错误 [ReferenceError: $ is not defined].
我的 Typescript 代码在这里
export function hello(element) : void {
$(element).toggleClass('abc');
};
我的单元测试代码如下:
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();
});
});
当我 运行 Mocha 测试时它显示
<failure message="$ is not defined"><![CDATA[ReferenceError: $ is not defined ...
]]></failure>
也尝试使用 global.$ = require("jquery"); 但没有用。
如上所述,您应该正确导入 jQuery:import $ = require('jquery');
jQuery 必须全局可用,因为您的脚本从全局 space 获取它。如果我修改您的代码,将 var $ = require('jquery')(window);
替换为:
global.$ = require('jquery')(window);
然后就可以了。注意这两个调用:第一个要求 jquery
,然后通过传递 window
来构建它。您也可以这样做:
global.window = window
global.$ = require('jquery');
如果 window
全局可用,则无需执行第一个代码段中的双重调用:jQuery 仅使用全局可用的 window
.
您可能还想定义 global.jQuery
,因为某些脚本依赖于它的存在。
这是运行的测试文件的完整示例:
/// <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();
});
});
typings
文件是使用 tsd
的通常方式获得的。文件 ./global.d.ts
修复了在 global
上设置新值时可能遇到的问题。它包含:
declare namespace NodeJS {
interface Global {
window: any;
$: any;
}
}
dummy.js
也被修改成这样:
declare var $: any;
export function hello(element) : void {
$(element).toggleClass('abc');
};
您需要先在 Node 中包含 jsdom 和 jQuery:
npm install jsdom --save-dev
npm install jquery --save-dev
然后将此行添加到您使用 jQuery
的 .js 文件中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;
如果您不能或不想更改全局命名空间类型定义,您仍然可以包含 jQuery,如下所示:
const globalAny:any = global;
const $ = globalAny.$ = require('jquery')(window);
jQuery 的完整初始化变为:
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = (new JSDOM());
const globalAny:any = global;
const $ = globalAny.$ = require('jquery')(window);
我在 2020 年发现了这个问题,路易斯让我指出了正确的方向。但是,我发现 jsdom-global
一种更简单的替代方法,可以让文档在 Mocha 中工作。
我按照 jsdom-global
jsdom-global
我使用这些行让 jQuery 和 $ 按预期工作:
require('jsdom-global')();
global.window = window;
global.$ = require('jquery');
global.jQuery = $;
那么这个测试就顺利通过了:
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));
});
});
});