使用 axios、pusher 和/或窗口对象上的 Echo 进行访问和取消导入

问题描述 投票:0回答:1

我正在使用

vitest
@vue/test-utils
来测试 Laravel/Vue3 UI。
boostrap.js
文件将
axios
pusher
Echo
添加到窗口对象,然后组件就可以直接使用它们而无需导入:

import axios from 'axios';
window.axios = axios;

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.baseURL = '/api';

import Echo from 'laravel-echo';

import Pusher from 'pusher-js';
window.Pusher = Pusher;

window.Echo = new Echo(...);

这是我的 vite.config.js 文件:

import { defineConfig } from 'vite';
import { fileURLToPath, URL } from 'node:url';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import Unimport from 'unimport/unplugin';

export default defineConfig({
  plugins: [
    laravel({
      input: [
        'resources/sass/app.scss',
        'resources/js/app.js',
      ],
      refresh: true,
    }),
    vue({
      template: {
        transformAssetUrls: {
          base: null,
          includeAbsolute: false,
        },
      },
    }),
    Unimport.vite({
      addons: {
        vueTemplate: true,
      },
      presets: [
        'vue',
        'vue-router',
        'pinia',
      ],
      imports: [
        { name: 'default', as: 'messages', from: '../../../utils/messages.js' }
      ]
    })
  ],
  test: {
    coverage: {
      provider: 'istanbul',
      reporter: ['text', 'lcovonly', 'html'],
    },
    environment: 'happy-dom',
  },
  resolve: {
    alias: {
      vue: 'vue/dist/vue.esm-bundler.js',
      '@': fileURLToPath(new URL('./resources/js', import.meta.url))
    },
  },
});

如何/在哪里更新它,以便如果我模拟 axios、pusher 和/或 Echo,我就可以编写测试而不会遇到像

ReferenceError: Echo is not defined
ReferenceError: axios is not defined
这样的错误?这是我成功嘲笑 Echo 的示例:

vi.mock('laravel-echo', async () => {
  const actual = vi.importActual('laravel-echo');

  return {
    ...actual,
    default: {
      private: vi.fn(() => {
        return {
          listenToAll: vi.fn(),
        };
      }),
    },
  };
});

但是当组件与 Echo 交互而不导入它时,会出现

ReferenceError: Echo is not defined
错误。添加
import Echo from 'laravel-echo';
可以消除错误,但我希望我的测试与 UI 环境相匹配,这样我就不需要为组件可访问的内容添加导入。

此外,虽然导入会在测试期间消除错误,但它会开始在实际浏览器中抛出错误

Uncaught (in promise) TypeError: Echo.private is not a function at...

太棒了;如何模拟

bootstrap.js
中发生的引导,以便我可以模拟已添加到窗口对象的任何依赖项并与之交互,例如 axios、pusher、lodash、Echo...?

vuejs3 vite jsdom laravel-echo vitest
1个回答
0
投票

假设 Chrome 71+、Firefox 65+、Safari 12.1+ 和 Node.js 12+,检查您的模拟并将必要的依赖项附加到

globalThis
对象。
请参阅“什么是 globalThis,以及为什么应该开始使用它?”,来自 Faraz Kelhini,,2019 年 12 月。

创建一个新文件

tests/bootstrap.js
,并在此文件中,向
globalThis
对象添加必要的依赖项:

// tests/bootstrap.js

import axios from 'axios';
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

globalThis.axios = axios;
globalThis.Pusher = Pusher;

// Mock the Echo instance with a jest mock function
// Adjust the mock implementation as necessary for your tests
globalThis.Echo = {
  private: jest.fn(() => ({
    listenToAll: jest.fn(),
  })),
};

// Configure axios as in bootstrap.js
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
axios.defaults.baseURL = '/api';

接下来,更新您的 Vite 配置,以将此引导文件包含在您的测试设置中。调整

vite.config.js
文件以引用
tests/bootstrap.js
配置中的
test
文件:

// vite.config.js

export default defineConfig({
  // ...
  test: {
    // ...
    runner: {
      runner: "jest",
    },
    setupFiles: [
      './tests/bootstrap.js',  // Adjust the path as necessary
    ],
    // ...
  },
  // ...
});

最后,在您的 Vitest 模拟设置中,由于您使用

vi.mock
来模拟您的
laravel-echo
,请确保返回实际的全局
Echo
实例(现在是您的模拟版本),而不是模拟新的一:

vi.mock('laravel-echo', async () => {
  return globalThis.Echo;
});

通过此设置,您的全局依赖项应该被模拟并在您的测试文件中可用,就像它们在您的应用程序文件中一样。

© www.soinside.com 2019 - 2024. All rights reserved.