使用 Jest 对 V-If 标签进行单元测试始终为真
Unit test a V-If label with Jest is alway true
我正在尝试使用 Jest 测试以下标签:
<label class="no-content-label" v-if="products.length===0 && !isTableBusy">No Content To Show</label>
通过以下测试:
it('Test No Content To Show When table is not empty', async () => {
const wrapper = mount(productTable, {
propsData: {
products: items1,
fields: fields1
}
})
expect(wrapper.find(".no-content-label").exists()).toBeFalsy()
wrapper.destroy();
})
其中项目只是:[{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }]
坚果我总是得到 True,即使组件没有显示并且应该得到 false。
完整组件代码:
<template>
<div id="ProductTable" class="container mt-3 mb-5">
<h1 class="mainTitle">Product Table Home</h1>
<b-alert variant="danger" :show="showError" v-for="(error,index) in errorArray" :key="index" dismissible>
{{ error }}
</b-alert>
<b-row class="mb-3">
<b-col md="3">
<b-form-input v-model="filterInput" type="search" id="filterInput" placeholder="Type to Search"></b-form-input>
</b-col>
</b-row>
<b-table id="product-table" striped hover head-variant="light"
:busy="isTableBusy"
:items="products"
:filter="filterInput"
:fields="fields"
:bordered="bordered"
:borderless="bordered"
:total-rows="rows">
<template #table-busy>
<div class="text-center text-danger my-2">
<b-spinner class="align-middle"></b-spinner>
<strong>Loading...</strong>
</div>
</template>
<template #cell(cogs.unitManufacturingCost)="row">
{{
row.item.cogs.unitManufacturingCost ? Number(row.item.cogs.unitManufacturingCost).toLocaleString() + '$' : '0$'
}}
</template>
<template #cell(cogs.shipmentUnitCost)="row">
{{ row.item.cogs.shipmentUnitCost ? Number(row.item.cogs.shipmentUnitCost).toLocaleString() + '$' : '0$' }}
</template>
<template #cell(cogs.monthlyAdvertismentCost)="row">
{{
row.item.cogs.monthlyAdvertismentCost ? Number(row.item.cogs.monthlyAdvertismentCost).toLocaleString() + '$' : '0$'
}}
</template>
<template #cell(cogs.manufacturingCountry)="row">
{{ row.item.cogs.manufacturingCountry ? row.item.cogs.manufacturingCountry : '-' }}
</template>
<template #cell(actions)="row">
<b-button size="md" variant="primary" @click="openEditProductModal(row.item)">
Edit
</b-button>
<edit-product-modal ref="EditProductModal" :item="row.item" @fetchProducts="fetchProducts"></edit-product-modal>
</template>
</b-table>
<label class="no-content-label" v-if="products.length===0 && !isTableBusy">No Content To Show</label>
</div>
</template>
<script>
import EditProductModal from "@/components/EditProductModal";
import {BAlert} from "bootstrap-vue";
import {BRow} from "bootstrap-vue";
import {BCol} from "bootstrap-vue";
import {BFormInput} from "bootstrap-vue";
import {BTable} from "bootstrap-vue";
export default {
name: "BootstrapProductTable",
components: {
EditProductModal: EditProductModal,
'b-alert': BAlert,
'b-row': BRow,
'b-col': BCol,
'b-form-input': BFormInput,
'b-table': BTable,
},
data() {
return {
filterInput: "",
bordered: true,
isTableBusy: false,
products: [],
fields: [
{key: 'productName', label: 'Product Name', sortable: true, sortDirection: 'desc'},
{key: 'cogs.unitManufacturingCost', label: 'Unit manufacturing cost', sortable: true,},
{key: 'cogs.shipmentUnitCost', label: 'Shipment unit cost', sortable: true},
{key: 'cogs.monthlyAdvertismentCost', label: 'Monthly advertising cost', sortable: true,},
{key: 'cogs.manufacturingCountry', label: 'Manufacturing country', sortable: true,},
{key: 'actions', label: 'Actions'}
],
errorArray: [],
showError: false
}
},
computed: {
rows() {
return this.products.length;
}
},
created() {
this.fetchProducts();
},
methods: {
openEditProductModal(row) {
this.$refs.EditProductModal.show(row)
},
async fetchProducts() {
try {
this.isTableBusy = true;
//delay example
// const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
// await delay(1000)
let response;
response = await this.axios.get(
"http://localhost:3000/products"
);
this.products = response.data;
} catch (error) {
this.showError = true;
this.errorArray = error.response ? error.response.data.errors : [error]
}
this.isTableBusy = false;
}
}
}
</script>
您正在尝试通过 products
,但您的组件不需要任何道具。
我看到 products
是在 fetchProducts
方法中获取的。所有 api 调用都必须被模拟。 fields
已在组件中设置。所以你所要做的就是模拟 api 调用。这就是为什么我建议你模拟 fetchProducts
方法,这样它总是会返回相同的数组 products
:
const mockProducts = [{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }];
it('Test No Content To Show When table is not empty', async () => {
const wrapper = mount(productTable, {
mocks: {
fetchProducts: () => mockProducts
}
})
expect(wrapper.find(".no-content-label").exists()).toBeFalsy()
wrapper.destroy();
})
我终于能够通过向标签添加 id 属性并通过 id 找到它来修复测试:
标签:
<label id="no-content-label" v-if="products.length===0 && !isTableBusy">No Content To Show</label>
工作测试:
let wrapper = null
beforeEach(() => {
wrapper = mount(ProductTable)
})
afterEach(() => {
wrapper.destroy()
})
it('Test "No Content To" Show appear When Products are empty', async () => {
await wrapper.setData({products: []})
expect(wrapper.find('[id="no-content-label"]').exists()).toBe(true)
expect(wrapper.find('[id="no-content-label"]').text()).toBe("No Content To Show");
})
it('Test "No Content To" not Show do not appear When Products are not empty', async () => {
await wrapper.setData({products: mockProduct})
expect(wrapper.find('[id="no-content-label"]').exists()).toBe(false);
})
我正在尝试使用 Jest 测试以下标签:
<label class="no-content-label" v-if="products.length===0 && !isTableBusy">No Content To Show</label>
通过以下测试:
it('Test No Content To Show When table is not empty', async () => {
const wrapper = mount(productTable, {
propsData: {
products: items1,
fields: fields1
}
})
expect(wrapper.find(".no-content-label").exists()).toBeFalsy()
wrapper.destroy();
})
其中项目只是:[{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }]
坚果我总是得到 True,即使组件没有显示并且应该得到 false。
完整组件代码:
<template>
<div id="ProductTable" class="container mt-3 mb-5">
<h1 class="mainTitle">Product Table Home</h1>
<b-alert variant="danger" :show="showError" v-for="(error,index) in errorArray" :key="index" dismissible>
{{ error }}
</b-alert>
<b-row class="mb-3">
<b-col md="3">
<b-form-input v-model="filterInput" type="search" id="filterInput" placeholder="Type to Search"></b-form-input>
</b-col>
</b-row>
<b-table id="product-table" striped hover head-variant="light"
:busy="isTableBusy"
:items="products"
:filter="filterInput"
:fields="fields"
:bordered="bordered"
:borderless="bordered"
:total-rows="rows">
<template #table-busy>
<div class="text-center text-danger my-2">
<b-spinner class="align-middle"></b-spinner>
<strong>Loading...</strong>
</div>
</template>
<template #cell(cogs.unitManufacturingCost)="row">
{{
row.item.cogs.unitManufacturingCost ? Number(row.item.cogs.unitManufacturingCost).toLocaleString() + '$' : '0$'
}}
</template>
<template #cell(cogs.shipmentUnitCost)="row">
{{ row.item.cogs.shipmentUnitCost ? Number(row.item.cogs.shipmentUnitCost).toLocaleString() + '$' : '0$' }}
</template>
<template #cell(cogs.monthlyAdvertismentCost)="row">
{{
row.item.cogs.monthlyAdvertismentCost ? Number(row.item.cogs.monthlyAdvertismentCost).toLocaleString() + '$' : '0$'
}}
</template>
<template #cell(cogs.manufacturingCountry)="row">
{{ row.item.cogs.manufacturingCountry ? row.item.cogs.manufacturingCountry : '-' }}
</template>
<template #cell(actions)="row">
<b-button size="md" variant="primary" @click="openEditProductModal(row.item)">
Edit
</b-button>
<edit-product-modal ref="EditProductModal" :item="row.item" @fetchProducts="fetchProducts"></edit-product-modal>
</template>
</b-table>
<label class="no-content-label" v-if="products.length===0 && !isTableBusy">No Content To Show</label>
</div>
</template>
<script>
import EditProductModal from "@/components/EditProductModal";
import {BAlert} from "bootstrap-vue";
import {BRow} from "bootstrap-vue";
import {BCol} from "bootstrap-vue";
import {BFormInput} from "bootstrap-vue";
import {BTable} from "bootstrap-vue";
export default {
name: "BootstrapProductTable",
components: {
EditProductModal: EditProductModal,
'b-alert': BAlert,
'b-row': BRow,
'b-col': BCol,
'b-form-input': BFormInput,
'b-table': BTable,
},
data() {
return {
filterInput: "",
bordered: true,
isTableBusy: false,
products: [],
fields: [
{key: 'productName', label: 'Product Name', sortable: true, sortDirection: 'desc'},
{key: 'cogs.unitManufacturingCost', label: 'Unit manufacturing cost', sortable: true,},
{key: 'cogs.shipmentUnitCost', label: 'Shipment unit cost', sortable: true},
{key: 'cogs.monthlyAdvertismentCost', label: 'Monthly advertising cost', sortable: true,},
{key: 'cogs.manufacturingCountry', label: 'Manufacturing country', sortable: true,},
{key: 'actions', label: 'Actions'}
],
errorArray: [],
showError: false
}
},
computed: {
rows() {
return this.products.length;
}
},
created() {
this.fetchProducts();
},
methods: {
openEditProductModal(row) {
this.$refs.EditProductModal.show(row)
},
async fetchProducts() {
try {
this.isTableBusy = true;
//delay example
// const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
// await delay(1000)
let response;
response = await this.axios.get(
"http://localhost:3000/products"
);
this.products = response.data;
} catch (error) {
this.showError = true;
this.errorArray = error.response ? error.response.data.errors : [error]
}
this.isTableBusy = false;
}
}
}
</script>
您正在尝试通过 products
,但您的组件不需要任何道具。
我看到 products
是在 fetchProducts
方法中获取的。所有 api 调用都必须被模拟。 fields
已在组件中设置。所以你所要做的就是模拟 api 调用。这就是为什么我建议你模拟 fetchProducts
方法,这样它总是会返回相同的数组 products
:
const mockProducts = [{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }];
it('Test No Content To Show When table is not empty', async () => {
const wrapper = mount(productTable, {
mocks: {
fetchProducts: () => mockProducts
}
})
expect(wrapper.find(".no-content-label").exists()).toBeFalsy()
wrapper.destroy();
})
我终于能够通过向标签添加 id 属性并通过 id 找到它来修复测试:
标签:
<label id="no-content-label" v-if="products.length===0 && !isTableBusy">No Content To Show</label>
工作测试:
let wrapper = null
beforeEach(() => {
wrapper = mount(ProductTable)
})
afterEach(() => {
wrapper.destroy()
})
it('Test "No Content To" Show appear When Products are empty', async () => {
await wrapper.setData({products: []})
expect(wrapper.find('[id="no-content-label"]').exists()).toBe(true)
expect(wrapper.find('[id="no-content-label"]').text()).toBe("No Content To Show");
})
it('Test "No Content To" not Show do not appear When Products are not empty', async () => {
await wrapper.setData({products: mockProduct})
expect(wrapper.find('[id="no-content-label"]').exists()).toBe(false);
})