Mock module does not work when imported in vue sfc files in typescript
leifmarcus opened this issue · 9 comments
Describe the bug
When importing the library plyr
inside a Vue 3 SFC and mock it inside a test file, it will not be mocked. Instead the actual library is used inside the vue file.
Reproduction
Considering having a component as follows
<template>
<div></div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import Plyr from 'plyr';
export default defineComponent({
name: 'TestComponent',
setup() {
console.log(Plyr);
return {};
},
});
</script>
within the test the plyr library is mocked:
import { mount } from '@vue/test-utils';
import { vi } from 'vitest';
import TestComponent from './TestComponent.vue';
const onFunction = vi.fn();
vi.mock('plyr', () => {
const plyrLib = vi.fn(() => ({
on: onFunction,
}));
return {
default: plyrLib,
};
});
describe('TestComponent', () => {
it('should register events', () => {
mount(TestComponent);
expect(onFunction).toHaveBeenCalled();
});
});
When running the test, the actual Plyr class will be logged instead of the mocked library.
System Info
System:
OS: macOS 12.4
CPU: (10) x64 Apple M1 Pro
Memory: 176.62 MB / 32.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 14.15.4 - ~/.nvm/versions/node/v14.15.4/bin/node
npm: 6.14.10 - ~/.nvm/versions/node/v14.15.4/bin/npm
Browsers:
Chrome: 102.0.5005.115
Chrome Canary: 105.0.5118.3
Firefox: 101.0
Safari: 15.5
npmPackages:
@vitejs/plugin-legacy: ^1.8.1 => 1.8.2
@vitejs/plugin-vue: ^2.3.3 => 2.3.3
vite: ^2.9.12 => 2.9.12
vitest: ^0.14.2 => 0.14.2
Used Package Manager
npm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
I had a similar issue and the comment below solved my problem.
#1450 (comment)
At the top of my test file, I now have:
const doSomething = vi.fn()
vi.resetModules()
import ...
vi.mock('@/helpers/functions', () => {
return {
doSomething,
}
})
Hello @OneFourFree, thank you for the response. I did already test your solution before I added this issue (I should have mention that in my description).
In my case this approach does not help. The plyr
library is still not mocked. I think it might be related to imports from node_modules, that cannot be mocked?
UPDATE
I also added an example test on stackblitz. You get an error there that window.matchMedia
is not defined, but this is not the problem I'm pointing at. If the mocking would work, the error would not appear.
As I was investigating this issue a bit further I found, that other libraries can be mocked for instance like @vueuse/..
without any problems.
I also found, that when creating a file that has export { default } from 'plyr'
and import that file in my component, then the mocking works as expected. I then mock the export of this file instead of mocking 'plyr'
directly
The next thing I tried was to directly mock the selected file inside the plyr
bundle. So what worked for now is to import the library inside the component as before
// inside component
import Plyr from 'plyr';
and use mocking like
// vitest requests the module version of the plyr and if
// the correct file is mocked, the mocking will work.
vi.mock('plyr/dist/plyr.min.mjs', () => {
// ...
})
This seems to be only related to the plyr
library as I can see so far. I'm not sure, if this is to be considered as a bug. But this seems to be related to the module resolution that vite/vitest is internally using.
There is a bug/inconsistency in Vite (vitejs/vite#8659), and because of that we resolved paths differently, when processing vi.mock
and import
.
This change should fix that on Vitest side: #1506
@sheremet-va, today I tried the plyr
library with Vitest version 0.16.0
and it seems, that the problem is not solved with this fix. I still need to mock the full file path to plyr/dist/plyr.min.mjs
.
Yeah, the fix would only work if you were doing vi.mock
inside a Vue file. You need to wait for vitejs/vite#8659 to be fixed
Should be fixed by #1919
I had a similar issue and the comment below solved my problem. #1450 (comment)
At the top of my test file, I now have:
const doSomething = vi.fn() vi.resetModules() import ... vi.mock('@/helpers/functions', () => { return { doSomething, } })
it works for me! thank you!