I've been asked to research unit testing Javascript on a legacy app that does not use JS modules (import/export). The app has JS object/prototypes in external .js files that are included via script src and more recently some Vue 2 components in .vue files using PHP include('mycomponent.vue').
All the examples for various unit testing frameworks assume JS modules are used. Can Vue be tested without modules?
I'm a bit lost and I am looking for direction, advice, and/or code examples of tests.
Thanks. Your help is much appreciated.
Here is a sample component:
PHP view (.phtml)
<?php include 'mycomponent.vue' ?>
<script type="text/javascript">
Vue.use(Vuex);
Vue.use(BootstrapVue);
Vue.component('v-select', VueSelect.VueSelect);
const i18n = new VueI18n({
locale: 'en',
dateTimeFormats: {
en: {
long: {
year: 'numeric', month: 'long', day: 'numeric',
hour: 'numeric', minute: 'numeric',
timezone: 'EST',
},
},
},
messages: {
en: <?= json_encode([
'messages' => 'etc'
]) ?>,
}
});
const store = new Vuex.Store({
state: {
//etc
}
});
new Vue({
el: '#wrapper',
store,
i18n,
data() {
return <?= json_encode([
'something' = [
bits: 'Bob'
]
]) ?>;
},
});
</script>
<div id="wrapper" v-cloak>
<mycomponent
:something="something"
></mycomponent>
</div>
mycomponent.vue
<template id="mycomponent_tmpl">
<div>
{{currentMessage}}
</div>
</template>
<script>
Vue.component('mycomponent', {
template: '#mycomponent_tmpl',
props: {
something: {
type: Object,
required: true,
}
},
data() {
return {
this.message = 'Hello World'
}
},
created() {
},
mounted() {
},
watch: {
},
computed: {
currentMessage() {
return this.message + ' ' + this.something.bits;
}
},
methods: {
}
});
</script>
So I eventually answered my own question here. Hope this helps someone else that is adding vue into a legacy app and wants to do some testing. It's not perfect as calling methods in the test doesn't seem to update the outerHTML at expect time although if I output the vue instance to the browser console the outHTML is updated then. Not sure how to access the changes during the tests yet but this is a decent start.
hello-world.vue
<template id="hello_world_tmpl">
<div>{{getMessage}}</div>
</template>
<script>
Vue.component('HelloWorld', {
template: '#hello_world_tmpl',
props: {
message: {
type: String,
required: true,
}
},
data() {
return {
msg: this.message
};
},
computed: {
getMessage() {
return this.msg;
}
},
methods: {
newMessage(msg) {
this.msg = msg;
}
}
});
</script>
I used php include in the Jasmine SpecRunner to add the vue file
Spec file
it('HelloWorld should not be null', function() {
let vm = new Vue({
template: `<HelloWorld message="Hi There!"></HelloWorld>`
}).$mount();
expect('<div>Hi There!</div>').toEqual(vm.$el.outerHTML);
vm.$children[0].newMessage('Test');
expect('Test').toEqual(vm.$children[0].msg);
});