Не может импортировать файл javascript в утилиты тестирования vue

Я тестирую один файл vue, который импортирует файл Javascript.

//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, поэтому он не будет определен, если вы попытаетесь его импортировать.

Thomas Lombart 26.10.2018 08:19

Я загрузил код. как видите, я мог импортировать этот файл и создать объект Worker, но при тестировании я не мог даже импортировать.

Royal.O 26.10.2018 08:57

@ThomasLombart Web-воркеры работают таким образом, весь файл обрабатывается как воркер, вы не пишете его как модуль. Проблема в другом.

Adam Jagosz 20.08.2019 11:38
0
3
592
1

Ответы 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) });
  }
}

Обратите внимание, что вам следует установить onmessage перед вызовом postMessage. Для настоящего работника это не имеет значения, потому что он вызывается асинхронно, но наш макет синхронный, поэтому в PasswordModal.vue он должен быть:

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

Связанный Разрешение импорта с помощью worker-loader webpack в тестах Jest.

Другие вопросы по теме