Reputation: 6986
I have this component in my codebase,
<template>
<v-dialog v-model="modalVisible" content-class="muc-modal" max-width="350" persistent>
<v-card>
<component :is="component"/>
</v-card>
</v-dialog>
</template>
<script lang="ts">
import Vue from 'vue';
import { Component, Watch } from "vue-property-decorator";
import { namespace } from "vuex-class";
const Modal = namespace("Modals");
@Component
export default class AppModal extends Vue {
public component: any = null;
@Modal.State
public modalVisible!: boolean;
@Modal.State
public modalComponent!: string;
@Modal.State
public modalComponentPath!: string|null;
get injectedComponent() {
return this.modalComponent;
}
@Modal.Mutation
public hideModal!: () => void
@Watch('injectedComponent')
onModalComponent(componentName: string) {
if(!componentName) return;
this.component = Vue.component(componentName, () => import(`./${this.modalComponentPath}`));
}
}
</script>
<style scoped lang="scss">
.muc-modal {
width:350px;
max-width:90%;
}
</style>
It is modal component that takes another component, this is run via mutation on the modal store,
import { VuexModule, Module, Mutation, Action } from "vuex-module-decorators";
@Module({ namespaced: true })
export default class Modals extends VuexModule {
//#region "State"
public modalVisible: boolean = false;
public modalComponent: string|null = null;
public modalComponentPath: string|null = null;
//#endregion "State"
//#region "Mutations"
@Mutation
public showModal(modalComponent:string, modalComponentPath: string|null = null) {
this.modalVisible = true;
this.modalComponent = modalComponent
this.modalComponentPath = modalComponentPath ? modalComponentPath : modalComponent
}
@Mutation
public hideModal() {
this.modalVisible = false;
this.modalComponent = null;
this.modalComponentPath = null;
}
//#endregion "Mutations"
//#region "Getters"
get getVisibility(): boolean {
return this.modalVisible
}
//#endregion "Getters"
//#region "Actions"
//#endregion "Actions"
}
I am wanting to write some tests that a) test the modal display correctly when showModal()
mutation is run, b) that it gets hidden correctly when hideModal()
mutation is run.
This is my current test file,
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import Modals from '@/store/modal';
import AppModal from '@/components/AppModal.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('AppModal.vue', () => {
let store: any = null;
//let mutations = modals.mutations
beforeEach(() => {
store = new Vuex.Store({
modules: {
"modals" : Modals
}
})
});
it('shows modal when modalVisible is set to true', () => {
console.log(store);
const wrapper = shallowMount(AppModal, {store, localVue});
// const modal = wrapper.find('.muc-modal')
// console.log(modal);
})
});
running this test I get the following response,
console.error node_modules/vuex/dist/vuex.common.js:916 [vuex] module namespace not found in mapState(): Modals/
console.error node_modules/vuex/dist/vuex.common.js:916 [vuex] module namespace not found in mapState(): Modals/
console.error node_modules/vue/dist/vue.runtime.common.dev.js:621 [Vue warn]: Error in render: "TypeError: Cannot read property 'template' of null"
found in ---> <AppModal>
and i have no clue why, can anyone help shed some light on this for me?
Upvotes: 1
Views: 1757
Reputation: 8123
This error -
TypeError: Cannot read property 'template' of null
Is a direct result of this coding error -
<component :is="null" />
Why?
The component tag should never have a null value for the is
attribute, even if it's momentary. null
isn't a valid component, and Jest correctly finds this error even when you don't see it in the browser.
In your above code, the initial value for the property component
(which is probably a bad variable name) is null
, so that's where this is coming from. A simple fix would be to set a valid component as an initial value so that it is never null.
Upvotes: 1