I've noticed some things that do not work with the composition API in testing.
setValue(xxx) does nothing
resource here
wrapper.vm does not include the component state for reference
resource here
<template>
<div class="mt-4 flex px-3 py-2 text-gray-800 rounded-full bg-gray-300">
<input
v-model="newTitle"
@keydown.enter="submit"
class="mx-2 bg-gray-300"
aria-label="New Item Title"
/>
<button @click="submit" class aria-label="Create New Item">
<PlusSvg classes="h-6 w-6" />
</button>
</div>
</template>
<script lang="ts">
import { createComponent, ref } from '@vue/composition-api';
import PlusSvg from '@/components/svg/PlusSvg.vue';
export default createComponent({
setup(_, { emit }) {
const newTitle = ref('');
function submit() {
if (!newTitle.value.trim()) return;
emit('submit', newTitle.value.trim());
newTitle.value = '';
}
return { newTitle, submit };
},
components: { PlusSvg }
});
</script>
import { shallowMount } from '@vue/test-utils';
import NewItem from '@/components/NewItem.vue';
import Vue from 'vue';
import CompositionApi from '@vue/composition-api';
Vue.use(CompositionApi);
describe('NewItem', () => {
test('is a Vue instance', () => {
const wrapper = shallowMount(NewItem);
expect(wrapper.isVueInstance()).toBeTruthy();
});
test('initializes with empty input', () => {
const wrapper = shallowMount(NewItem);
expect(wrapper.find('input').text()).toBe('');
});
test('cannot submit with empty input', () => {
const wrapper = shallowMount(NewItem);
wrapper.find('button').trigger('click');
expect(wrapper.emitted().submit).toBeFalsy();
});
test('submit bubbles event with input', async () => {
const wrapper = shallowMount(NewItem);
const newTodoTitle = 'Go to the store';
wrapper.find('input').setValue(newTodoTitle);
wrapper.find('button').trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.emitted().submit[0]).toBe(newTodoTitle);
});
test('input is cleared after submit', async () => {
const wrapper = shallowMount(NewItem);
const newTodoTitle = 'Take out the trash';
expect(wrapper.find('input').is('input')).toBeTruthy();
wrapper.find('input').setValue(newTodoTitle);
await wrapper.vm.$nextTick();
expect(wrapper.find('input').text()).toBe(newTodoTitle);
wrapper.find('button').trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.find('input').text()).toBe('');
});
});
Hey,
I had similar issue and I found out that I didn't pass local vue to shallowMount.
Instead of creating new Vue instance, try to use createLocalVue from vue test utils.
import { createLocalVue, shallowMount } from '@vue/test-utils'
import CompositionApi from '@vue/composition-api';
import NewItem from '@/components/NewItem.vue';
const localVue = createLocalVue()
localVue.use(CompositionApi)
const wrapper = shallowMount(NewItem , {
localVue
})
...
EDIT: it seems to be fine:) I messed up.
I'm also experienceing an issue with .emitted()
const inputListeners = {
input: (event) => {
console.log(event.target.name); // this prints correct value during test
emit('input', event.target.value, event.target.name, event);
},
};
wrapper.emitted().input // this is [ [''] ]
@MartinMalinda a more complete example would be helpful.
@LinusBorg my apologies! On a second try it works well. It seems like I wasn't reemitting an event correctly.
@PrzemyslawPolrolniczak I was having the same issue, but this works for me too. Thank you.
No need to use createLocalVue,
import CompositionApi from '@vue/composition-api';
import Vue from 'vue';
Vue.use(CompositionApi);
const wrapper = mount(YourComponent);
works also.
If you use jest or mocha, you can setup a setupFiles
//jest.config.js
module.exports = {
setupFiles: [
"<rootDir>/__tests__/setupTest.js",
],
}
// __tests__/setupTest.js
import Vue from 'vue';
import CompositionApi from '@vue/composition-api';
Vue.use(CompositionApi);
// test.spec.js
// tests should work as expected
I'm going to close this issue, if you're still facing issues, please reopen or create a new issue.
Most helpful comment
Hey,
I had similar issue and I found out that I didn't pass local vue to
shallowMount.Instead of creating new Vue instance, try to use
createLocalVuefrom vue test utils.