无法在 vue 测试工具中导入 javascript 文件

Posted

技术标签:

【中文标题】无法在 vue 测试工具中导入 javascript 文件【英文标题】:can't import javascript file in vue test utils 【发布时间】:2019-03-30 18:56:20 【问题描述】:

我正在测试一个导入 javascript 文件的 vue 文件。

//unlockWallet.worker.js

import  Wallet, Configs  from '@/helpers';

function create(password) 
  const createdWallet = ;
  const wallet = new Wallet.generate();
  createdWallet.walletJson = wallet.toV3(password, 
    kdf: Configs.wallet.kdf,
    n: Configs.wallet.n
  );
  createdWallet.name = wallet.getV3Filename();
  return createdWallet;


onmessage = function(event) 
  if (event.data.type === 'createWallet') 
    const workerResult = create(event.data.data[0]);
    postMessage(workerResult);
  
;

和 PasswordModal.vue 我像这样导入 unlockWallet.worker.js 文件。

import Worker from '@/workers/unlockWallet.worker.js'

methods: 
    unlockWallet() 
      const worker = new Worker();
      const self = this;
      worker.postMessage(
        type: 'unlockWallet',
        data: [this.file, this.password]
      );
      worker.onmessage = function(e) 
        // Regenerate the wallet since the worker only return an object instance. Not the whole wallet instance
        self.$store.dispatch(
          'decryptWallet',
          BasicWallet.unlock(
            type: 'manualPrivateKey',
            manualPrivateKey: Buffer.from(e.data._privKey).toString('hex')
          )
        );
      ;
    

在 PasswordModal.spec.js 中

import shallowMount from '@vue/test-utils'
import PasswordModal from '@/layouts/PasswordModal.vue';

而我没有通过这个测试。

测试套件无法运行 ReferenceError: onmessage 未定义

【问题讨论】:

据我所知,您的unlockWallet.worker.js 文件中没有导出任何内容,因此如果您尝试导入它,它将不会被定义。 我已经上传了代码。如您所见,我可以导入该文件并创建 Worker 对象,但在测试中,我什至无法导入。 @ThomasLombart 网络工作者以这种方式工作,整个文件作为工作者处理,你不把它写成一个模块。问题出在其他地方。 【参考方案1】:

您真正想做的是导入一个 Web Worker,而不仅仅是任何 JavaScript 文件,而且这些文件只能在浏览器中工作。

您可以尝试jsdom-worker,它模拟 Node 的工作程序,但我无法使其与 Webpack 一起工作,所以如果您使用 Webpack 及其worker-loader 插件,您可能希望完全模拟工作程序测试。

首先将您的功能从工作文件中分离到unlockWallet.js

import  Wallet, Configs  from '@/helpers';

function create(password) 
  const createdWallet = ;
  const wallet = new Wallet.generate();
  createdWallet.walletJson = wallet.toV3(password, 
    kdf: Configs.wallet.kdf,
    n: Configs.wallet.n
  );
  createdWallet.name = wallet.getV3Filename();
  return createdWallet;


export default function(eventData) 
  if (eventData.type === 'createWallet') 
    const workerResult = create(eventData.data[0]);
    postMessage(workerResult);
  
;

然后您的工作人员将只导入它。 unlockWallet.worker.js:

import workerFunction from "./unlockWallet.js";

self.onmessage = async function (event) 
  self.postMessage(workerFunction(event.data));
;

这样你就可以模拟工人了。 test/mocks/unlockWallet.worker.js:

import workerFunction from "../../src/unlockWallet.js"; // or wherever you keep it

export default class Worker 
  constructor() 
    // should be overwritten by client code
    this.onmessage = () =>  ;
  

  // mock expects data:   instead of e:  data:   
  postMessage(data) 
    // actual worker implementation wraps argument arg into  data: arg ,
    // so the mock needs to fake it 
    this.onmessage( data: workerFunction (data) );
  

请注意,您应该在调用postMessage 之前设置onmessage。对于真正的工作人员来说,这无关紧要,因为它是异步调用的,但我们的模拟是同步的,因此在PasswordModal.vue 中应该是:

 worker.onmessage = function(e) 
   // ...
 ;
 worker.postMessage(
    type: 'unlockWallet',
    data: [this.file, this.password]
  );

相关Resolving imports using webpack's worker-loader in Jest tests。

【讨论】:

以上是关于无法在 vue 测试工具中导入 javascript 文件的主要内容,如果未能解决你的问题,请参考以下文章

无法在 vue 中导入 Observable

无法在nuxt vue组件中导入引导程序[重复]

无法在 nativescript vue 中导入 @nota/nativescript-webview-ext/vue

由于在现有项目中导入了特定的库,因此无法在 Eclipse 中解决导入问题

无法从 npm 包中导入 vue 组件

尝试在 Django 应用程序的 js 文件中导入 vue.js 时出现“未捕获的语法错误:无法在模块外使用 import 语句”