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

时间:2018-10-26 04:39:16

标签: testing vue.js vue-component jestjs vuex

我正在测试一个导入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

1 个答案:

答案 0 :(得分:0)

您真正想做的是导入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) });
  }
}

请注意,您应在致电onmessage之前设置postMessage。对于真正的工作者,这无关紧要,因为它被异步调用,但是我们的模拟是同步的,因此在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