Fra*_*eto 5 vuejs2 vue-test-utils
发出更改组件数据的一个变量的ajax请求后,我正在尝试测试Vue应用程序的模板。此变量(书籍)用于有条件地渲染画廊
语境:我想创建一个画廊,以显示我在后端存储的书。为此,我获取了有关安装组件的书籍。其结果在变量簿中设置。我要测试的是,在ajax调用之后,该组件将书籍与画廊一起呈现
问题:设置books变量后,<div v-else-if='books.length > 0'>SHOW GALLERY</div>
应该呈现div ,但是<div v-else class='loader'>Loading</div>
仍然呈现“ else” div()
接下来的两个代码块是组件和测试本身:
BookGallery.vue(正在测试的组件)
<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>
Run Code Online (Sandbox Code Playgroud)
测试
@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');
});
}
Run Code Online (Sandbox Code Playgroud)
问题:如何为最后一个断言更新DOM--
see("SHOW GALLERY")
?
更新
请参见函数 该函数仅在vue-test-utils用于安装应用程序的包装器中搜索HTML元素。在这种情况下,由于我将其保留为空,因此它将在整个HTML文件中搜索文本“ SHOW GALLERY”
export const see = (text: string, selector?: string) => {
const wrap = selector ? wrapper.find(selector) : wrapper;
expect(wrap.html()).contains(text);
};
Run Code Online (Sandbox Code Playgroud)
小智 14
我刚刚解决了一个类似的问题,使用了shallowMount 及其sync: false
选项。
这会停用同步渲染,要求您给渲染器一些时间以await wrapper.vm.$nextTick()
在需要时执行其工作 ( )。完成此操作后,根据我的反应数据重新渲染组件,正如预期的那样。
Luk*_*sák 11
我遇到了非常相似的问题,并await wrapper.vm.$forceUpdate();
在断言失败之前解决了它。这会强制 Vue 更新视图。
Lan*_*ana 11
最初 Vue Test Utils 同步运行更新。但后来他们取消了同步模式。他们在这里解释了原因并展示了如何编写测试:
测试代码将从这里更改:
Run Code Online (Sandbox Code Playgroud)it('render text', (done) => { const wrapper = mount(TestComponent) wrapper.trigger('click') wrapper.text().toContain('some text') })
对此:
Run Code Online (Sandbox Code Playgroud)it('render text', async () => { const wrapper = mount(TestComponent) wrapper.trigger('click') await Vue.nextTick() wrapper.text().toContain('some text') })
因此,要解决您的问题,您需要await wrapper.vm.$nextTick()
在断言之前添加see('SHOW GALLERY');