使用ES导入时,如何在ts-jest中使用jQuery编写测试?

时间:2019-07-12 09:32:14

标签: jquery jsdom ts-jest

我正在尝试使用TypeScript,Jest和jQuery编写单元测试。我走得很远,但是运行测试时,出现“ jQuery需要带有文档的窗口”

显然,问题在于import * as $ from "jquery"see this question)也将初始化jQuery,但那时没有窗口。我需要的是jQuery模块的“惰性”版本,类似于$(document).ready(...)通常的形式,只是$符号本身。

背景:我已将jQuery安装为npm install @types/jquery。我正在使用jsdom创建一个假窗口。我正在使用ts-jest将TS文件转换为jest的JavaScript。使用npx jest --watchnpm t运行测试。

我想避免在Jest setupFile中使用global.$,因为许多测试不需要开销。

1 个答案:

答案 0 :(得分:0)

我有一个解决方案,但是您不能在测试的代码中使用$,因此它仅适用于您编写/可以更改的代码。

而不是直接使用$,而是将其包装在提供程序中:

export class JQueryProvider {
    constructor(public jq: any) {
        // empty
    }

    get(selector: string): JQuery {
        return this.jq(selector)
    }
}

这样,我们可以隐藏$来源的详细信息。即使输入get()的类型为jqany方法也会将结果转换为正确的类型。

此代码应进入共享实用程序模块。

测试应包括具有以下设置代码的模块:

import { JQueryProvider } from "./utils"
import { JSDOM } from "jsdom";

export type WithJQueryFunction = (jq: JQueryProvider) => void;

export function withJQuery(fn: WithJQueryFunction): void {
    // Create window before loading jquery
    const window = new JSDOM().window 

    // Create jQuery instance
    const $ = require('jquery')(window);

    // Create provider to avoid the global variable $
    const jq = new JQueryProvider($)

    fn(jq)
}

请注意,由于我不确定如何实现相同的效果,因此我使用的是require()而不是import

测试现在看起来像这样:

withJQuery((jq) => {
    describe('jQuery tests', () => {
        it('empty div', () => {
            const parent = jq.get('<div>')
            expect(parent[0]).toMatchSnapshot()
        })      

        it('empty div with class', () => {
            const parent = jq.get('<div>').addClass('foo')
            expect(parent[0]).toMatchSnapshot()
        })      
    })
})

生产代码示例:

export class DivAppender implements Appender {
    constructor(public jq: JQueryProvider, public parent: JQuery, public dateFormat = TIME_FORMAT) {
        // empty
    }

    append(event: LogEvent): void {
        const element = this.jq.get('<div>').addClass('event')
        ...

const appender = new DivAppender(new JQueryProvider($), $('body'))
相关问题