如何使用Jest编写JavaScript模块揭示模式的单元测试?

4
例如:我的math_util.js是
var MathUtil = function(){
  function add(a,b){
    return a + b;
  }
  return {
    add: add
  };
}

我将使用Jest来测试add()函数。因此,我会编写以下代码:
test('add', ()=>{
  expect(MathUtil().add(1,1)).toBe(2);
});

但是我得到了“MathUtil未定义”或“MathUtil()不是函数”的错误。

我还尝试使用require()import。 但是MathUtil没有module.exportexport

那么如何使用Jest编写javascript揭示模块模式的单元测试呢?

注意:我的项目中所有脚本都是使用揭示模块模式编写的,因此将所有脚本转换为ES2015模块可能并不实际。


你的测试范围内是否有 MathUtil 函数?似乎测试没有以任何方式导入它。 - Tsvetan Ganev
如何将 MathUtil 添加到作用域中?MathUtil 没有任何导出,因此我认为无法使用 import。 - Chanh
如果您以这种方式编写了整个项目,那么其他文件如何找到您的实用函数? - Jared Smith
@Chanh,你需要重写所有内容以添加导出/导入。在Node中没有window,并且顶层变量声明不像在浏览器中那样在全局范围内。你考虑过使用浏览器内测试运行程序和phantom吗? - Jared Smith
1
@JaredSmith 为了完整起见:默认的 Jest 环境是 jsdom,其中包括一个 window 对象,可以使用 setupFiles 来设置诸如全局变量之类的东西...话虽如此,我同意模块绝对是最佳实践。 - Brian Adams
显示剩余2条评论
2个回答

3

如果您真的想按原样测试math_util.js,您可以这样做:

// ---- math_util.test.js ----
const fs = require('fs');
const path = require('path');
const vm = require('vm');

const code = fs.readFileSync(path.join(__dirname, '/math_util.js'), 'utf-8');
const MathUtil = vm.runInThisContext(code + '; MathUtil');

test('add', ()=>{
  expect(MathUtil().add(1,1)).toBe(2);
});

......但最好的做法是将代码重构为模块。对于揭示模块模式来说,这应该是一个非常直接的过程,只需要删除外部包装函数和返回的对象,并在返回的对象中添加export即可:

// ---- math_utils.js ----
export function add(a,b){
  return a + b;
}


// ---- math_utils.test.js ----
import { add } from './math_utils';

test('add', ()=>{
  expect(add(1,1)).toBe(2);
});

那么没有办法将 MathUtil 添加到 window 中,以便 Jest 可以像在 test() 中调用 window.MathUtl 一样访问它吗?恐怕更新每个文件以具有 module.exports 是唯一的选择。 - Chanh
1
虽然这个回答中的信息是正确的,但实际上并没有回答问题。 - Jared Smith
@Chanh 我更新了我的答案,说明了如何在不修改 math_utils.js 的情况下进行测试。 - Brian Adams

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接