-
Notifications
You must be signed in to change notification settings - Fork 665
Open
Description
Subject of the issue
Given a basic component, with setup script, if we use the function useSlots()
, the component cannot be rendered with mount
.
Steps to reproduce
I created a brand new project with create-vue@2, with typescript and vitest :
PS D:\dev\cfdp> npm create vue@2
Vue.js - The Progressive JavaScript Framework
√ Project name: ... vue-test2
√ Add TypeScript? ... No / Yes
√ Add JSX Support? ... No / Yes
√ Add Vue Router for Single Page Application development? ... No / Yes
√ Add Pinia for state management? ... No / Yes
√ Add Vitest for Unit Testing? ... No / Yes
√ Add Cypress for End-to-End testing? ... No / Yes
√ Add ESLint for code quality? ... No / Yes
Now the basic component, SlotComponent.vue :
<template>
<div>
<slot name="body"></slot>
</div>
</template>
<script setup lang="ts">
import { useSlots } from 'vue';
const slots = useSlots();
</script>
The associated test, SlotComponent.spec.ts :
import { describe, expect, it } from 'vitest';
import { mount } from '@vue/test-utils';
import SlotComponent from './SlotComponent.vue'
describe('Slot test', () => {
it('will fail', () => {
const wrapper = mount(SlotComponent, {
slots: {
body: '<div>body</div>'
}
});
expect(wrapper.text()).toContain('body');
});
});
Expected behaviour
the test should pass, (it pass if i remove the code const slots = useSlots()
)
Actual behaviour
the test fail with the stacktrace below :
stderr | src/components/__tests__/SlotComponent.spec.ts > Slot test > will fail
[Vue warn]: useContext() called without active instance.
[Vue warn]: Error in setup: "TypeError: Cannot read properties of null (reading '_setupContext')"
found in
---> <SlotComponent> at D:/dev/cfdp/vue-test/src/components/__tests__/SlotComponent.vue
<Root>
TypeError: Cannot read properties of null (reading '_setupContext')
at getContext (D:/dev/cfdp/vue-test/node_modules/vue/dist/vue.runtime.esm.js:2589:15)
at Module.useSlots (D:/dev/cfdp/vue-test/node_modules/vue/dist/vue.runtime.esm.js:2567:12)
at setup (D:/dev/cfdp/vue-test/src/components/__tests__/SlotComponent.vue:8:41)
at invokeWithErrorHandling (D:\dev\cfdp\vue-test\node_modules\vue\dist\vue.runtime.common.dev.js:2919:30)
at initSetup (D:\dev\cfdp\vue-test\node_modules\vue\dist\vue.runtime.common.dev.js:2352:29)
at initState (D:\dev\cfdp\vue-test\node_modules\vue\dist\vue.runtime.common.dev.js:5300:5)
at VueComponent.Vue._init (D:\dev\cfdp\vue-test\node_modules\vue\dist\vue.runtime.common.dev.js:5615:9)
at new VueComponent (D:\dev\cfdp\vue-test\node_modules\vue\dist\vue.runtime.common.dev.js:5750:18)
at createComponentInstanceForVnode (D:\dev\cfdp\vue-test\node_modules\vue\dist\vue.runtime.common.dev.js:4490:12)
at init (D:\dev\cfdp\vue-test\node_modules\vue\dist\vue.runtime.common.dev.js:4352:54)
❯ src/components/__tests__/SlotComponent.spec.ts (1)
❯ Slot test (1)
× will fail
✓ src/components/__tests__/HelloWorld.spec.ts (1)
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
FAIL src/components/__tests__/SlotComponent.spec.ts > Slot test > will fail
TypeError: Cannot read properties of null (reading '_setupContext')
❯ getContext node_modules/vue/dist/vue.runtime.esm.js:2589:15
2587| }
2588| var vm = currentInstance;
2589| return vm._setupContext || (vm._setupContext = createSetupContext(vm));
| ^
2590| }
2591| /**
❯ Module.useSlots node_modules/vue/dist/vue.runtime.esm.js:2567:12
❯ setup src/components/__tests__/SlotComponent.vue:8:41
❯ invokeWithErrorHandling node_modules/vue/dist/vue.runtime.common.dev.js:2919:30
❯ initSetup node_modules/vue/dist/vue.runtime.common.dev.js:2352:29
❯ initState node_modules/vue/dist/vue.runtime.common.dev.js:5300:5
❯ VueComponent.Vue._init node_modules/vue/dist/vue.runtime.common.dev.js:5615:9
❯ new VueComponent node_modules/vue/dist/vue.runtime.common.dev.js:5750:18
❯ createComponentInstanceForVnode node_modules/vue/dist/vue.runtime.common.dev.js:4490:12
❯ init node_modules/vue/dist/vue.runtime.common.dev.js:4352:54
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯
Test Files 1 failed | 1 passed (2)
Tests 1 failed | 1 passed (2)
Time 3.70s (in thread 64ms, 5780.13%)
Annex :
my package.json :
{
"name": "vue-test",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "run-p type-check build-only",
"preview": "vite preview --port 4173",
"test:unit": "vitest --environment jsdom",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false"
},
"dependencies": {
"vue": "^2.7.7"
},
"devDependencies": {
"@types/jsdom": "^16.2.14",
"@types/node": "^16.11.45",
"@vitejs/plugin-legacy": "^2.0.0",
"@vitejs/plugin-vue2": "^1.1.2",
"@vitejs/plugin-vue2-jsx": "^1.0.2",
"@vue/test-utils": "^1.3.0",
"@vue/tsconfig": "^0.1.3",
"jsdom": "^20.0.0",
"npm-run-all": "^4.1.5",
"terser": "^5.14.2",
"typescript": "~4.7.4",
"vite": "^3.0.2",
"vitest": "^0.18.1",
"vue-template-compiler": "^2.7.7",
"vue-tsc": "^0.38.8"
}
}
n-buck
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
treardon17 commentedon Nov 28, 2022
In addition to
useSlots
, this also happens withuseAttrs
,useListeners
, andgetCurrentInstance
(using"vue": "~2.7.13"
and"@vue/test-utils" : "1.3.x"
). I cannot run unit tests while using script setup in combination with any one of those methods. Currently using vitest0.23.4
as the test runner. Also worth noting this happens withmount
as well asshallowMount
.rossinek commentedon Feb 13, 2023
Quick workaround for vitest (fixes
useListeners
usage):piktur commentedon Jul 5, 2023
@rossinek how does this solve the issue? This mock does not change the implementation of
useListeners
. The private module variablecurrentInstance
referenced ingetContext
will still be undefined.Unless mocking prevents inconsistent module resolution. Whilst debugging I've noticed both vitest
vue/dist/vue.js
andvue/dist/vue.esm.js
are loaded.rossinek commentedon Jul 5, 2023
@piktur thank for taking a look at this. It was a long time ago and TBH I don't remember why it works and currently I don't have the capacity to debug it once again but I created a little reproduction for you if you want to dive in. To see the difference run:
tobi-fis commentedon Feb 5, 2024
Any news on this? Some component logic I need to test relies onuseSlots
and I still getCannot read properties of null (reading 'setupContext')
when running the test.Update for anyone struggling with this:
The solution was to put the call to useSlots() into the top-level of your components' script setup block (or setup function). I had placed it inside a function before, heres the before/after example:
Wrong:
Correct:
Currently using: