使用 Mocha 使用 Typescript 对 Jquery 进行单元测试时,如何解决“$ 未定义”错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38590957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:41:07  来源:igfitidea点击:

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

jqueryunit-testingtypescriptmochajsdom

提问by Aditi

I am writing Mochaunit tests for Typescriptcode containing Jquery. I'm using jsdomfor getting the document object. When I compile my TS code to JS and run the tests, it throws an error [ReferenceError: $ is not defined].

我正在为包含Jquery 的Typescript代码编写Mocha单元测试。我正在使用jsdom来获取文档对象。当我将 TS 代码编译为 JS 并运行测试时,它会引发错误[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

当我运行 Mocha 测试时,它显示

    <failure message="$ is not defined"><![CDATA[ReferenceError: $ is not defined ...
]]></failure>

Also tried using global.$ = require("jquery");but does not work.

也尝试使用global.$ = require("jquery"); 但不起作用。

回答by Louis

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:

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

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:

那么它的工作原理。注意这两个调用:第一个是 require jquery,然后是通过传递window. 你也可以这样做:

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

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

如果window全局可用,则不需要像第一个片段中那样执行双重调用:jQuery 只使用全局可用的window.

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

您可能还想定义,global.jQuery因为某些脚本依赖于它的存在。

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 typingsfiles are obtained the usual way using tsd. The file ./global.d.tsfixes the issue you may get with setting new values on global. It contains:

这些typings文件是使用tsd. 该文件./global.d.ts解决了在 上设置新值时可能遇到的问题global。它包含:

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

dummy.jswas also modified like this:

dummy.js也被修改成这样:

declare var $: any;

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

回答by Jorge Luis Monroy

You need to include jsdom and jQuery in Node first:

你需要先在 Node 中包含 jsdom 和 jQuery:

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

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

然后将此行添加到您使用 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;

回答by TinkerTank

If you can't or don't want to alter the global namespace type definition, you can still include jQuery, as following:

如果您不能或不想更改全局命名空间类型定义,您仍然可以包含 jQuery,如下所示:

const globalAny:any = global;
const $ = globalAny.$ = require('jquery')(window);

The full initialization of jQuery then becomes:

jQuery 的完整初始化然后变成:

const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = (new JSDOM());
const globalAny:any = global;
const $ = globalAny.$ = require('jquery')(window);

回答by Yahiko

As said, you should import jQuery properly: import $ = require('jquery');

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