如何使用SystemJS动态模拟ES6模块?

时间:2016-06-03 16:21:29

标签: testing ecmascript-6 systemjs

我有一个用ES6编写的单页面应用程序。将服务器端的代码转换为babelJs的经典javascript,然后由SystemJs加载。

我的html文件中存在Javascript:

System.config({
  baseURL: '/js',
  meta: {
    '/js/*': { format: 'cjs' }
  }});
System.defaultJSExtensions = true;
System.import("index.js")
    .catch(function (error) {
        console.error(error)
    });

index.js:

import f1 from 'file1';
import f2 from 'file2';

// code here ...

一切正常。已加载index.js,并且所有import语句都已正确执行。

现在,我想创建一些带有模拟ES6模块的页面,用于测试目的。我的目标是通过用其他静态测试类替换模型类(包含在ES6模块中)来显示页面。

假设我有3个文件:real_model.jsfake_model.jscomponent.jscomponent.js导入真实模型(import Model from 'real_model';)。

如何动态地替换伪造的模型(在组件中)?

1 个答案:

答案 0 :(得分:0)

自问题发布以来已经有一段时间了,但也许这个解决方案可能对其他人有帮助。

使用SystemJS,可以使用System.newModule即时创建模块。然后,您可以使用System.set用新的模块覆盖现有模块。在我们的测试中,我们使用以下辅助函数来模拟现有模块:

function mockModule(name, value) {
  const normalizedName = System.normalizeSync(name);
  System.delete(normalizedName);
  System.set(normalizedName, System.newModule(Object.assign({ default: value }, value)));
}

然后,例如在beforeEach回调中,我们分配模拟,然后使用System.import导入要测试的模块:

let [component, fake_model] = [];

beforeEach(() => {
  // define mock
  fake_model = { foo: 'bar' };

  // overwrite module with mock
  mockModule('real_model', fake_model);

  // delete and reimport module
  System.delete(System.normalizeSync('component'));
  return System.import('src/testing').then((m) => {
    component = m.default;
  }).catch(err => console.error(err));
});

// test your component here ...

这种方法的一大优点是您不需要额外的模拟库,它只适用于SystemJS。