Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue test utils is updating the component data but not re-rendering the dom

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);
};
like image 450
Fran Roa Prieto Avatar asked Dec 14 '18 14:12

Fran Roa Prieto


2 Answers

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.

like image 89
Brice Pernet Avatar answered Oct 07 '22 00:10

Brice Pernet


I ran into very similar problem and solved it with await wrapper.vm.$forceUpdate(); before assertion that failed. This forces Vue to update view.

like image 31
Lukáš Irsák Avatar answered Oct 06 '22 22:10

Lukáš Irsák