Unit Testing: A Vue App using Vuetify and Vuex

Save time setting up unit testing of vue apps that integrate vuetify and vuex.

I am not completely convinced of the value in unit testing vue applications, yet. Cypress end-to-end tests tend to catch the difficult to find bugs lurching at the integration points better. But, time will tell how I divide the testing between vue test utils and cypress.

The Project setup

  • vuetify
  • vue-cli
  • vuex

The Testing setup

  • vue test utils
  • jest test runner

I had already written a proof of concept project when I tried to add the unit tests. But whenever I wrote a test, I would get the error below. So, I decided to start a new project following the ‘Step by Step Guide’ by Dávid Gergely referenced below. I finally discovered I needed to add a store to my unit test in order to get the test to run. See below for more details on the challenge and solution.

A Challenge

The unit test would blow up with the following error.

1
2
3
4
5
6
7
8
node:internal/process/promises:225
          triggerUncaughtException(err, true /* fromPromise */);
          ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "TypeError: Cannot read property '_modulesNamespaceMap' of undefined".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

A Solution

The error was fixed by declaring a store with modules in the beforeEach test block. Then, passing that store into the shallowMount command that sets up the wrapper.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { shallowMount, createLocalVue } from "@vue/test-utils";
import Vuex from "vuex";
import Vuetify from "vuetify";
import AccountsList from "@/pages/AccountsList.vue";
import accounts from "@/store/modules/accounts.js";
import transactions from "@/store/modules/transactions.js";
describe("AccountsList.vue", () => {
  let localVue;
  let vuetify;
  let wrapper;
  let store;

  beforeEach(() => {
    localVue = createLocalVue();
    localVue.use(Vuex);
    vuetify = new Vuetify();
    store = new Vuex.Store({
      modules: {
        trans: transactions,
        accounts: accounts
      }
    });
    wrapper = shallowMount(AccountsList, {
      localVue,
      store,
      vuetify,
      attachTo: document.body
    });
  });
  it("should render the data table", () => {
    expect(wrapper.find('[data-testid="account-list-data-table"]').exists()).toBe(true);
  });
});

Let’s have a conversation!

What kind of testing do you finding valuable? I am super interested in leveling up my Vue testing.

Please check in with me on twitter. My Twitter handle is @ardith_falkner.

References