TypeError:使用Svelte和Jest时Select不是构造函数

问题描述

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

TestSelect.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
  }

我想知道我是否错过了一个开玩笑的配置选项。预先感谢

解决方法

因此,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文件,如您所见here。这个文件被玩笑所理解,并导致您的错误:

TypeError:Select不是构造函数

库将Svelte组件导出到Select.js文件中。可以被您的应用程序和玩笑所理解。

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

import Select from 'svelte-select/Select';

像那样,开玩笑会理解它会导入.svelte文件,并应使用svelte-jester转换器对其进行编译。

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

 "main": "Select.js",

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

,

我能够通过使用汇总将测试捆绑在一起,然后在捆绑的输出上开玩笑地解决此问题。 this blog post中描述了类似的方法。

,

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

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

Jest 配置文件


  "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"
    }
  }