【问题标题】:Testing JavaScript without exports using the Jest testing framework使用 Jest 测试框架在不导出的情况下测试 JavaScript
【发布时间】:2018-12-09 17:06:22
【问题描述】:

我正在将旧的 JS 代码库迁移到现代 JS。第一步是向当前代码库添加一些测试。当前的代码库本质上是一堆单独的 JS 文件,每个文件都包装在一个 IIFE 中。

这本身就是测试的问题,因为除非某些东西暴露给全局对象,否则您无法进入 IIFE。我正在重构的一些代码是带有属性的简单 JS 对象,它附加到全局对象上的命名空间(下面的namespace 只是一个占位符名称),例如:

var namespace = window.namespace || {};
var paymentsHandlerUtils = {
    getNewValue: function(selectedAmount) {
        'use strict';
        return selectedAmount < 1 || isNaN(selectedAmount)
            ? ''
            : '$' + selectedAmount;
    },
    getSelectedAmount: function(value) {
        'use strict';
        return value % 1 === 0 ? parseInt(value) : parseFloat(value).toFixed(2);
    }
};

namespace.paymentsHandlerUtils = paymentsHandlerUtils;

我的问题是,您将如何使用 Jest 进行测试?我已尝试要求上述内容如下:

const paymentsHandlerUtils = require('../js/components/payments/payments-handler-utils.js');

这会运行,但 paymentsHandlerUtils 对象只是一个空的 {}。这并不奇怪,因为简单地执行 JS 并没有返回任何内容。但是,window.namespace 也未定义。似乎代码没有在 jsDOM 的上下文中执行,所以没有创建全局。

有没有办法让它工作,或者这根本不是 Jest 的用例?提前致谢。

【问题讨论】:

  • 我与rewire 一起进入了兔子洞,它声称可以满足您的需求。也许你可以让它发挥作用。

标签: javascript jestjs


【解决方案1】:

我认为没有办法在导入时访问模块全局变量,因为它首先违反了封装模块的原则。

需要最少重构的另一种方法是将以下代码添加到所有模块中:

if (typeof exports === "object") {
    module.exports = paymentsHandlerUtils;
}
namespace.paymentsHandlerUtils = paymentsHandlerUtils;

它的灵感来自旧的 UMD(通用模块定义)。该条件检测您是否在 commonjs 环境中运行并导出您的变量。然后你就可以在你的测试中使用它了:

const paymentsHandlerUtils = require('../js/components/payments/payments-handler-utils.js');

否则你需要使用另一个在浏览器中工作的测试套件,因为 Jest 不能。

祝您迁移顺利!

【讨论】:

  • 谢谢安德烈亚!我正在考虑类似的事情,但有点担心生产中可能出现的问题。这听起来像是一种感觉安全的完全合法的方式。我要试试这个。
猜你喜欢
  • 2017-12-07
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 2020-08-26
  • 2022-08-22
  • 2018-08-06
  • 1970-01-01
  • 2018-06-25
相关资源
最近更新 更多