0
votes

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...????‍♂️.

2
try updating to capacitor 1.1.0, it was released a few hours ago and included a Jest related fixjcesarmobile
Yep, that...that did it 😐 Thank youCaleb Bergman

2 Answers

0
votes

EDIT

Although this made the test past, upgrading the @capacitor/core package to v1.1.0 (released just hours ago) resolved the issue, too.


Following the Jest docs on mocking Node modules - specifically scoped modules - I created a __mocks__ folder under root, created a directory underneath it named @capacitor and created a file underneath that called core.js. So I ended up with a structure like:

.
├─__mocks__
│ └─ @capacitor
│    └─ core.js

Inside of core.js I export the pieces that are imported by the Vue components I'm testing (currently only Plugins and Plugins.Filesystem):

// core.js
module.exports = {
  Plugins: {
    Filesystem: {}
  }
}

With those in place the Jest test passes with flying green colors.

0
votes

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