I'm trying to test the template of my Vue app after making an ajax request which is changing one variable of the component' data. This variable (books) is use to conditional render the gallery
CONTEXT: I want to create a gallery in order to show the books I have stored in my back end. For this, I fetching my books on mounting the component. The result of this is set in the variable books. What I'm trying to test is that, after the ajax call, the component renders the gallery with the books
PROBLEM: When the books variable is set, the div <div v-else-if='books.length > 0'>SHOW GALLERY</div>
should be rendered, but the "else" div (<div v-else class='loader'>Loading</div>
) is still rendered
The next two blocks of code are the component and the test itself:
BookGallery.vue (component I'm testing)
<template>
<v-content>
<v-container fluid>
/*** Conditional rendering: After the ajax request books > 0, so this div should be rendered ***/
<div v-if='books.length > 0'>SHOW GALLERY</div>
<div v-else class='loader'>Loading</div>
</v-container>
</v-content>
</template>
<script lang='ts'>
import {Component} from 'vue-property-decorator';
import {MyMixin} from '../mixin';
@Component({components: {BookInformation}})
export default class BookGallery extends MyMixin {
public books: string[] = [];
public async mounted() {
/*** books is set as the result of the ajax request ***/
this.books = (await this.$http.get(this.host + '/books')).data;
}
}
</script>
<style scoped lang='scss'></style>
TEST
@test
public async 'after calling the books, the gallery show all of them'() {
/*** MOCKING THE RESPONSE ***/
TestCase.OK_200({
books: [
{ uri: 'img/covers/1.jpg', title: 'El Prinicipito'},
{ uri: 'img/covers/2.jpeg', title: 'The Lord of the Rings'},
],
});
/*** MOUNTING MY COMPONENT ***/
const wrapper = TestCase.shallowMount(BookGallery);
/** ASSERTING **/
await flushPromises().then(() => {
/** the first "expect" passes, so books > 0 = true **/
expect(wrapper.vm.$data.books).to.eqls({
books: [
{ uri: 'img/covers/1.jpg', title: 'El Prinicipito'},
{ uri: 'img/covers/2.jpeg', title: 'The Lord of the Rings'},
],
});
/** This is failing. The application should read 'SHOW GALLERY' when books > 0 (something tested in the previous assert), as explained in the first comment of the component's template, but is not updating the dom, only the data **/
see('SHOW GALLERY');
});
}
The QUIESTION: How can I update my DOM for my very last assert -
see("SHOW GALLERY")
-?
UPDATE
see Function The function only searches for a HTML element in the wrapper that vue-test-utils is using for mounting the application. In this case, as I have left it null, it is searching the text "SHOW GALLERY" over the whole HTML file
export const see = (text: string, selector?: string) => {
const wrap = selector ? wrapper.find(selector) : wrapper;
expect(wrap.html()).contains(text);
};
I just solved a similar problem, using shallowMount and its sync: false
option.
This deactivates sync rendering, requiring you to give the renderer some time to perform its job (await wrapper.vm.$nextTick()
) where needed.
Once this done, the component was re-rendered based on my reactive data, as expected.
I ran into very similar problem and solved it with await wrapper.vm.$forceUpdate();
before assertion that failed. This forces Vue to update view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With