4

在为 Svelte 组件编写 Jest 测试TypeError: Select is not a constructor时,当组件使用 es6 导入语法导入库时出现错误。

测试选择.js:

<script>
  import Select from 'svelte-select';

  let items = [
    {value: 'chocolate', label: 'Chocolate'},
    {value: 'pizza', label: 'Pizza'},
    {value: 'cake', label: 'Cake'},
    {value: 'chips', label: 'Chips'},
    {value: 'ice-cream', label: 'Ice Cream'},
  ];
  
  let selectedValue = undefined;
</script>

<Select {items} bind:selectedValue></Select>


TestSelect.spec.js:

import '@testing-library/jest-dom/extend-expect';
import { render } from '@testing-library/svelte';

import TestSelect from './TestSelect.svelte';


describe('Component', () => {
  test('Should render', () => {
    const { container } = render(TestSelect, {});
    expect(true);
  });
});



笑话配置

 "jest": {
    "collectCoverage": true,
    "testResultsProcessor": "jest-sonar-reporter",
    "coveragePathIgnorePatterns": [
      "/node_modules/"
    ],
    "transform": {
      "^.+\\.js$": "babel-jest",
      "^.+\\.svelte$": "svelte-jester"
    },
    "moduleFileExtensions": [
      "js",
      "svelte"
    ],
    "setupFilesAfterEnv": [
      "@testing-library/jest-dom/extend-expect"
    ],
    "verbose": true
  }

我想知道是否有一个我错过的开玩笑配置选项。提前致谢

4

3 回答 3

4

所以 Jest 的主要问题是,默认情况下它会忽略node_folder. 因此,当 Jest 在您的代码中看到导入的 Svelte 库时,它不会在运行导致错误的测试之前编译它们。

一个解决方案是通过在 jest 配置中添加这个来告诉 jest 不要忽略该svelte-select库:

  transformIgnorePatterns: [
    'node_modules/(?!(svelte-select)/)' /* ignore node_module but not node_modules/svelte-select/* */
  ],

库本身的另一个问题是,默认导出的元素不是 Svelte 组件,而是预编译的简单.js文件,如您在此处看到的。开玩笑不理解此文件并导致您的错误:

TypeError:选择不是构造函数

该库将 Svelte 组件导出到Select.js文件中。这对于您的应用程序和玩笑是有效的。

因此,要解决您的问题,您应该使用以下方法导入此组件:

import Select from 'svelte-select/Select';

像这样,jest 会理解它导入了一个.svelte文件并应该使用svelte-jester转换器对其进行编译。

理想情况下,您可以要求库的作者默认使用 in 导出 Svelte 组件package.json

 "main": "Select.js",

我创建了一个仓库来向您展示工作配置:https ://github.com/johannchopin/test-svelte-component-in-node_module 。

于 2020-10-16T13:24:23.027 回答
1

我能够通过使用 rollup 首先捆绑我的测试然后在捆绑的输出上运行 jest 来解决这个问题。此博客文章中描述了类似的方法。

于 2020-10-16T13:05:50.240 回答
1

我解决了这个问题。我正在为我的苗条 APP 使用 Typescript。

// TestSelect.js:
import Select from 'svelte-select/Select';

笑话配置文件


  "jest": {
    "resetMocks": false,
    "transform": {
      "^.+\\.svelte$": [
        "svelte-jester",
        {
          "preprocess": true
        }
      ],
      "^.+\\.ts$": "ts-jest",
      "^.+\\.js$": "babel-jest"
    },
    "moduleFileExtensions": [
      "js",
      "ts",
      "svelte"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!(svelte-select))"
    ],
    "testPathIgnorePatterns": [
      "cypress"
    ],
    "moduleNameMapper": {
      ".css": "<rootDir>/empty-module.js",
      "intl-tel-input": "<rootDir>/user-intl-module.js"
    }
  }
于 2021-04-28T16:58:32.270 回答