【问题标题】:Is it possible to test with Jest an old non-module JavaScript?是否可以用 Jest 测试旧的非模块 JavaScript?
【发布时间】:2020-01-30 00:43:01
【问题描述】:

考虑一个旧项目(在我看来很常见):

static/
   js/
      file1.js
      file2.js
      ....
   index.html

index.html

...
<script type="text/javascript" src="js/file1.js"></script>
<script type="text/javascript" src="js/file2.js"></script>
...

file1.js:

// publicly exposed class/function
var Person = function(name, age) {
    this.name = name;
    this.age= age;
}
Person.prototype.getName = function() {
    return this.name + '(' + this.age   + ')'
}

file2.js:

// publicly exposed function
var createPerson = function(name) {
    return new Person(name);
}

file1.js 和 file2.js 的内容只是用来显示问题的虚拟内容。

能不能写个表格测试一下?:

file2.test.js:

// require('./file2');
// require('./file2');
test('create', () => {
    let person = createPerson('Tester', 40);
    expect(person.getName()).toBe('Tester (40)');
});

我尝试搜索将窗口/全局附加变量转换为模块导出的 babel 插件,也尝试使用 Jest 'setupFiles' 配置属性。 也许 Jest 不适合这种情况,只是不想寻找另一个测试框架,因为我已经将 Jest 用于其他现代模块化应用程序。

如果不是如何测试这样的旧应用程序 JavaScript - 我知道我可以使用 Jasmine 或 Mocha 并在浏览器中运行测试,但希望这发生在 Node 环境中,以便最终可以使用 CI 进行处理?

【问题讨论】:

    标签: javascript unit-testing jestjs


    【解决方案1】:

    您需要将文件的范围合并为当前上下文的一部分 - 例如通过同步加载和危险地evaling 源到当前测试文件中 - 使以这种方式导入的任何内容都可用于测试(包括潜在的意外冲突和副作用 - 就像在非模块化全局窗口上下文中一样) .

    const script = (url) => {
        const { protocol } = new URL(url, 'file://');
        switch (protocol) {
            case 'file:':
                return require('fs').readFileSync(`${process.cwd()}/${url}`, 'UTF8');
            case 'http:':
            case 'https:':
                return String(require('child_process').execSync(`wget -O - -o /dev/null '${url}'`))
            default:
                throw new Error('unsupported protocol');
        }
    };
    
    eval(script('js/file1.js'));
    eval(script('js/file2.js'));
    
    // ... tests 
    

    【讨论】:

    • 是的,我所做的是类似的事情,事实上,当在“jsdom”测试环境中运行时,创建“全局”上下文并将其传递给每个测试文件时,这就是 Jest 内部所做的方式。我使用 Node 的 vm.createContext() 并使用 vm.runInContext() 运行所有文件,然后将此上下文合并到稍后传递给测试文件的“全局”对象中
    • 谢谢@RumenNeshev!为了完整起见,我将补充一点,我已经简单地将上下文与Object.assign(global, context) 合并,以防有人想知道。正如最初期望在vm 下看到一个专用方法。
    猜你喜欢
    • 2018-09-14
    • 2018-03-11
    • 1970-01-01
    • 2015-02-05
    • 2019-05-28
    • 2021-08-27
    • 2019-07-11
    • 1970-01-01
    • 2017-06-18
    相关资源
    最近更新 更多