【问题标题】:Global function not available in Window object when using Jasmine & Headless Chrome使用 Jasmine 和 Headless Chrome 时,全局函数在 Window 对象中不可用
【发布时间】:2018-02-23 15:45:57
【问题描述】:

我很难弄清楚如何访问通常可用作浏览器中窗口对象的方法的函数。我正在使用 Karma、Headless Chrome 和 Jasmine。

这是我的问题的简化:

我有一个名为add-numbers-together.js的模块:

function addTogether(a, b) {
    return a + b;
}

(function(){
    addTogether(2,5);
})();

这个 Jasmine 测试正在测试它:

describe('add-numbers-together.js', function() {
    it('Should add numbers together', function() {
        require('module/add-numbers-together');
        console.info(window.addTogether);
    });
});

require 语句肯定是在检索模块 ok,我已经测试过了。

我希望 console.info 打印出函数的定义,就像我在实际浏览器中执行此操作时一样,但这个 console.info 返回 undefined这是为什么呢?在测试中需要模块后如何访问 addTogether 函数?

我猜这是 Jasmine 或 Headless Chrome 的一些怪癖,但无论我多么努力地搜索,我都无法在任何地方找到答案!

另外,请注意:我不想向模块本身添加任何测试代码,这不是我的选择。

【问题讨论】:

    标签: javascript jasmine karma-jasmine google-chrome-headless jasmine2.0


    【解决方案1】:

    我稍微改了一下测试,检查函数不是undefined,但是不管Chrome还是ChromeHeadless作为浏览器都失败了。

    describe('add-numbers-together.js', function() {
        it('Should add numbers together', function() {
            require('module/add-numbers-together');
            expect(window.addTogether).not.toBeUndefined();
        });
    });
    

    要获得通过此测试的版本,您有多种选择:

    1. 使被测代码成为真正的模块和export函数,然后将测试更改为import该模块(推荐)。如果使用 AMD,也可以是 definerequire
    2. 配置您的构建设置以在不更改代码的情况下从该模块强制使用全局export(webpack 可以做到这一点,这有点骇人听闻,但如果您无法编辑该脚本,它也可以工作)。这通常仅使用 3rd 方脚本完成。
    3. 将测试文件中的脚本内容放在测试代码上方(不推荐,因为您是复制粘贴,更改不会同步)。
    4. 加载待测脚本,然后加载夹具标记中的测试(有效,但有点蹩脚,因为您的测试夹具 HTML 现在硬编码脚本引用)。

    这是用函数的export 为选项#1 重写的测试代码。

    export function addTogether(a, b) {
        return a + b;
    }
    
    (function () {
        addTogether(2, 5);
    })();
    

    这里是用被测模块的import 为选项#1 重写的测试。

    import * as addNumbersTogether from 'add-numbers-together';
    
    describe('add-numbers-together.js', function () {
        it('Should add numbers together', function () {
            expect(addNumbersTogether.addTogether).not.toBeUndefined();
        });
    });
    

    【讨论】:

    • 这行得通吗?我的模块没有也不能具有 commonjs module.exports() 架构,因为它是一个自执行函数,将位于页面上的脚本标记中。如果我将模块保存到变量中,我看不到如何在测试中运行自执行函数。
    • 如果你想requireimport它,你必须defineexport它或者你可以将模块放在有测试代码而不是@987654338的页面中@它。
    • 啊,所以如果我试图测试一个将存在于页面上的脚本标记中的自执行函数,那么我不应该尝试在测试中要求它,而应该只添加脚本在测试夹具的脚本标签中?
    • 当我试图重现您的场景时,这对我有用。 1)使具有自执行功能的文件成为导出函数的真实模块(最好的方法),2)配置您的构建设置以强制从该模块进行全局导出而不更改代码(webpack 可以做到这一点, hackey,但是如果您无法编辑该脚本,则可以使用),3)将脚本内容放在测试代码之上(蹩脚,因为您正在复制粘贴),或 4)加载被测脚本,然后加载夹具中的测试标记(也很蹩脚,因为您的测试夹具硬编码了脚本引用)。
    • 你真的很有帮助。非常感谢你
    猜你喜欢
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 2017-04-16
    • 2016-11-10
    • 1970-01-01
    • 2019-09-18
    • 1970-01-01
    相关资源
    最近更新 更多