【问题标题】:Es6 global variable not available in classEs6 全局变量在类中不可用
【发布时间】:2016-02-10 14:11:47
【问题描述】:

我尝试让我的 window 变量在我的导入类中可用。在它说的导入类中,该窗口未定义。

我使用 mocha 和 chai 来测试我的 javascript 代码。还有 babeljs 用于 es6 部分。

这是我的 test.js:

import { jsdom } from 'jsdom';
import { assert } from 'chai';
import sinon from 'sinon';
import Pixels from './../src/pixels.es6';

let document, window, pixels;

describe('Pixels', () => {

    beforeEach(function () {
        let el;

        document = jsdom('<html><body></body></html>');
        window = document.defaultView;

        el = document.createElement('div');
        el.setAttribute('data-flow-id', Date.now());
        pixels = new Pixels(el);
    });

    describe('spawn()', function () {

        beforeEach(function () {
            window.dataLayer = {
                push: sinon.spy()
            };

            pixels.spawn();
        });

        afterEach(function () {
            window.dataLayer = {};
        });

        it('should push to dataLayer', function () {
            assert.isTrue(window.dataLayer.push.called);
        });

    });

});

这是 window 不可用的导入类:

import { URL } from './config.es6';
import Parse from './parse.es6';
import fetch from 'safe-fetch';

export default class Pixels {
    constructor (el) {
        console.log(window);
        this.el = el;
        this.fetch = fetch || window.fetch;
    }

    spawn () {
        this.fetch(URL, {
            reportChildRequestId: false,
            method: 'get'
        }).then(resp => {
            return resp.text();
        }).then(html => {
            // ... do stuff with html variable
        });
    }
}

摩卡电话是:mocha --require babel-core/register

除了将window 变量传递到构造函数中之外,还有其他方法可以使window 变量在Pixels 中可用吗?

【问题讨论】:

    标签: javascript mocha.js babeljs jsdom


    【解决方案1】:

    这是一种奇怪的行为。 我唯一能想到的是,这可能是 let 的行为范围问题?我知道它的范围权限略有不同,但我认为因为它是在全局范围内,所以这不是问题。您是否尝试过使用var document, window, pixels; 而不是let document, window, pixels;?除此之外,我没有看到任何问题。我希望这能有所帮助。如果你弄明白了请告诉我,我其实很好奇,谢谢!

    【讨论】:

    • var 不是问题所在。因此,与let 相同的未定义窗口对象。
    • @danbruegge 值得一试:D。很高兴您找到了解决方案!
    【解决方案2】:

    没有理由它应该起作用。 test.js 中的 window 变量在该文件的顶部范围内声明。 这不是全局的。 此外,jsdom 不会污染全局空间。所以你不能指望它来创建一个全局window

    您可能可以通过分配给global.window 来获得一些工作,但我不会这样做。如果您想测试要在浏览器中运行的代码,您应该让jsdom 加载它。这意味着将引用您的脚本的真实 HTML 页面传递给它。

    【讨论】:

    • “你应该让 jsdom 加载它”是什么意思?
    • 经过一番研究,我发现 mocha-jsdom 正在做我想做的事情。 :) npmjs.com/package/mocha-jsdom
    【解决方案3】:

    我找到了mocha-jsdom npm 包。有了这个包,我不需要创建windowdocument,因为它会为我做这一切,一切都按预期工作。

    更新代码:

    import { jsdom } from 'mocha-jsdom';
    import { assert } from 'chai';
    import sinon from 'sinon';
    import Pixels from './../src/pixels.es6';
    
    let pixels;
    
    describe('Pixels', () => {
    
        jsdom();
    
        beforeEach(function () {
            let el;
    
            el = document.createElement('div');
            el.setAttribute('data-flow-id', Date.now());
            pixels = new Pixels(el);
        });
    
        describe('spawn()', function () {
    
            beforeEach(function () {
                window.dataLayer = {
                    push: sinon.spy()
                };
    
                pixels.spawn();
            });
    
            afterEach(function () {
                window.dataLayer = {};
            });
    
            it('should push to dataLayer', function () {
                assert.isTrue(window.dataLayer.push.called);
            });
    
        });
    
    });
    

    【讨论】:

      猜你喜欢
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      • 2012-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多