Search code examples
vue.jsionic-frameworkjestjsvue-test-utilscapacitor

Jest testing Vue Single File Components with Ionic Capacitor plugin imports


GitHub repo of the issue.

I'm building an Ionic app using Vue and Capacitor. I'm setting up unit tests using vue-test-utils + Jest. Jest unit tests are failing trying to import Capacitor plugins into Vue Single File Components.

The Vue app was created using Vue CLI 3 (v3.4.0). CLI options included unit testing using Jest. I'm new to unit testing altogether. I've naively tried mocking the @capacitor/core module prior to importing the Vue component; this didn't help.

jest.config.js (Vue CLI default)

module.exports = {
  moduleFileExtensions: ["js", "jsx", "json", "vue"],
  transform: {
    "^.+\\.vue$": "vue-jest",
    ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$":
      "jest-transform-stub",
    "^.+\\.jsx?$": "babel-jest"
  },
  transformIgnorePatterns: ["/node_modules/"],
  moduleNameMapper: {
    "^@/(.*)$": "<rootDir>/src/$1"
  },
  snapshotSerializers: ["jest-serializer-vue"],
  testMatch: [
    "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"
  ],
  testURL: "http://localhost/",
  watchPlugins: [
    "jest-watch-typeahead/filename",
    "jest-watch-typeahead/testname"
  ]
};

MyComponent.vue

<template>...</template>
<script>
import { Plugins } from '@capacitor/core'
const { Filesystem } = Plugins
...
</script>

MyComponent.spec.js

import { shallowMount } from "@vue/test-utils";
import Component from "@/components/MyComponent.vue";
...

I expect the test to run without issue. Instead, I get the following error message when Jest tries to import the component on line 2 of the spec file:

TypeError: Cannot destructure property `Filesystem` of 'undefined' or 'null'.

      35 | <script>
      36 | import { Plugins } from '@capacitor/core'
    > 37 | const { Filesystem } = Plugins

Plugins is undefined on line 36, thusly line 37 complains when it attempts to destructure Filesystem from it.

In a browser, however, the Filesystem object is as follows:

{
  "config": {
     "name": "Filesystem",
     "platforms": ["web"]
  },
  "loaded": false,
  "listeners": {}, 
  "windowListeners":{},
  "DEFAULT_DIRECTORY": "DATA",
  "DB_VERSION": 1,
  "DB_NAME": "Disc",
  "_writeCmds": ["add","put","delete"]
}

I don't know where the issue lies. I don't know if I should be doing something different with Jest, I don't know if I shouldn't be importing Capacitor plugins directly in Vue SFCs like I've seen in some examples, or...🤷‍♂️.


Solution

  • Per @jcesarmobile's comment on the OP, updating @capacitor/core from version 1.0.0 to 1.1.0 resolved the issue entirely.

    Fix: make capacitor compatible with commonjs