Vitest: Cannot read properties of undefined (reading 'define


Topic: Vitest: Cannot read properties of undefined (reading 'defineComponent')

Hello,

I'm trying to implement a unit test using Vitest on a component that imports MDBAlert.

import { expect, test } from 'vitest';
import { mount, VueWrapper } from '@vue/test-utils';
import BaseWarning from '@/components/base/BaseWarning.vue';

test('mount BaseWarning', async () => {
    expect(BaseWarning).toBeTruthy();

    const wrapper: VueWrapper<any> = mount(BaseWarning, {
        props: {
            warningText: 'test'
        }
    });

    expect(wrapper.text()).toContain('test');
});

And I get the following error message when executing the unit tests.

 FAIL  components/__tests__/BaseWarning.test.ts [ components/__tests__/BaseWarning.test.ts ]
TypeError: Cannot read properties of undefined (reading 'defineComponent')
 ❯ ../../../../../../../../../../../../C:/src/SPA/webct/Vite_Typescript/webct-app/node_modules/mdb-vue-ui-kit/js/mdb.umd.min.js:1:299
 ❯ ../../../../../../../../../../../../C:/src/SPA/webct/Vite_Typescript/webct-app/node_modules/mdb-vue-ui-kit/js/mdb.umd.min.js:1:214
 ❯ ../../../../../../../../../../../../C:/src/SPA/webct/Vite_Typescript/webct-app/node_modules/mdb-vue-ui-kit/js/mdb.umd.min.js:1:234

I have tried to modify tsconfig.vitest.json to include mdb as a dependency without success. I have searched for the issue without getting anything similar. Has anyone encountered this problem?

Thank you.


Bartosz Cylwik staff answered 2 years ago

Hi! If i'm not wrong, you will have to mock our package in your testing component and use some testing environment that will help you emulate browser environment.

You can read more about mocking third-party-libraries here: https://vitest.dev/guide/mocking.html#modules

and about testing environments here: https://vitest.dev/guide/environment.html


I have tried some of that and came up with an example:

// @vitest-environment happy-dom

import { expect, test, vi } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import BaseWarning from "../src/App.vue";

vi.mock("mdb-vue-ui-kit", () => ({
  defineComponent: vi.fn(),
  MDBBtn: vi.fn(),
  MDBAlert: {
    props: {
      "v-model": Boolean,
      color: String,
      // other props
    },
    template: "<slot></slot>",
  },
}));

test("mount BaseWarning", async () => {
  expect(BaseWarning).toBeTruthy();

  const wrapper: VueWrapper<any> = mount(BaseWarning, {
    props: {
      warningText: "test",
    },
  });
  console.log("wrapper:", wrapper.text());
  expect(wrapper.text()).toContain("test");
});

I have created a mock component, with template inside Alert that will receive the slot value (because thats where I used the warningText prop in my vue component), so that the test value will be present in a wrapper content. I used simple mock for MDBBtn because it wasn't necessary to add anything more in my example.

I hope that will be helpful! Best Regards!


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Open

Specification of the issue
  • User: Free
  • Premium support: No
  • Technology: MDB Vue
  • MDB Version: MDB5 3.1.1
  • Device: PC
  • Browser: Chrome
  • OS: Windows 10
  • Provided sample code: No
  • Provided link: No