如何使用Mocha对使用Typescript的Jquery进行单元测试时修复“$ is not defined”错误?

时间:2016-07-26 13:17:14

标签: jquery unit-testing typescript mocha jsdom

我正在为包含 Jquery Typescript 代码编写 Mocha 单元测试。我正在使用 jsdom 来获取文档对象。当我将我的TS代码编译为JS并运行测试时,它会抛出错误 [ReferenceError:$未定义]

我的打字稿代码在这里

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”); 但不起作用。

5 个答案:

答案 0 :(得分:8)

jQuery必须全局可用,因为您的脚本从全局空间获取它。如果我修改您的代码,以便将var $ = require('jquery')(window);替换为:

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

然后它的工作原理。请注意两个调用:1st要求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');
};

答案 1 :(得分:1)

您需要首先在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;

答案 2 :(得分:0)

如果您不能或不想更改全局名称空间类型定义,则仍可以包括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);

答案 3 :(得分:0)

我在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));
        });
    });
});

答案 4 :(得分:-1)

如上所述,您应该正确导入jQuery:import $ = require('jquery');