Vue component testing with Jest error, TypeError: Cannot read property 'name' of undefined
Vue component testing with Jest error, TypeError: Cannot read property 'name' of undefined
我有一个带有以下模板的 Vue 组件。它接收一个对象作为道具。首先,它在 Admin.vue
中从 created()
的后端拉取,作为数组传递给 OrderList
,循环,然后作为单独的订单传递给 Order
。 <router-link>
中的 ShowOrder
组件在其自己的页面上显示单个订单。
<template v-if="order ? order : error">
<div class="order-container -shadow">
<div class="order-number">
<p>{{ order.orderId }}</p>
<p>{{ order.daySelected }}</p>
<p>{{ order.timeSelected }}</p>
</div>
<div class="customer-info">
<h2>{{ order.userInfo.name }}</h2>
<p>
{{ order.userInfo.street }},
{{ order.userInfo.city }}
</p>
<p v-if="order.userInfo.apt">
{{ order.userInfo.apt }}
</p>
<p>{{ order.userInfo.phone }}</p>
...
...
<router-link :to="{ name: 'ShowOrder', params: { id: order.orderId, order: order }}"
>Show Details</router-link
>
</div>
</template>
<script>
export default {
name: "Order",
props: {
order: {
type: Object,
default: function() {
return {};
}
}
},
data() {
return {
error: "Error"
};
}
};
</script>
我的Order.spec.js
如下:
const localVue = createLocalVue();
localVue.use(VueRouter);
const router = new VueRouter();
const $route = {
path: '"/show-order/:id"'
};
shallowMount(Order, {
localVue,
router,
stubs: ["router-link", "router-view"]
});
const mockOrder = {
orderId: 123,
chocolateChip: 24,
oatmeal: 0,
campfire: 12,
daySelected: "Wed Jan 27",
timeSelected: "2:30 - 3:00",
userInfo: {
apt: "",
city: "Port ",
email: "k@gmail.com",
street: " Point Road",
phone: "(123)446-1980",
name: "Mr.Smith"
}
};
describe("Order.vue", () => {
it("renders correctly", () => {
const wrapper = shallowMount(Order, {
localVue,
propsData: {
order: mockOrder,
$route
}
});
console.log(wrapper.html());
expect(wrapper.element).toMatchSnapshot();
});
});
我收到的错误如下所示:
FAIL tests/unit/Order.spec.js
● Test suite failed to run
TypeError: Cannot read property 'name' of undefined
72 | flex-flow: column wrap;
73 | margin-top: 1em;
> 74 | transition: all 0.2s linear;
| ^
75 | }
76 |
77 | .order-container:hover {
我什至无法进行快照测试。我在这里阅读了许多其他类似的问题并出现此错误,并尝试在模板中使用 v-if
在组件加载之前等待数据。这里发生了什么?如果这是一个对象错误,为什么在控制台中有一个指向我的作用域 css 而不是 order.userInfo.name
的指针?
我也试过从 Admin.vue
中的 created()
更改为 mounted()
。
在 Order.vue
中,我尝试添加对象以使其基于这些 Vue docs.
具有反应性
data() {
return {
error: "Error",
orderItem: {}
};
},
mounted() {
this.orderItem = Object.assign({}, this.order);
console.log(this.orderItem, "line 65");
}
您调用了 shallowMount()
两次:一次是在没有 mockOrder
的情况下在测试之外(并且没有必要进行此调用),另一次是在测试内部使用 mockOrder
。
// Order.spec.js
shallowMount(Order, { localVue }) // ❌ no props, but no need for this call
describe("Order.vue", () => {
shallowMount(Order, {
localVue,
propsData: {
order: mockOrder
}
})
})
第一次调用导致错误,因为它的 order
属性默认为空对象,因此 order.userInfo
将是 undefined
,导致 order.userInfo.name
的错误.
解决方案是删除不必要的第一次调用 shallowMount()
。
我有一个带有以下模板的 Vue 组件。它接收一个对象作为道具。首先,它在 Admin.vue
中从 created()
的后端拉取,作为数组传递给 OrderList
,循环,然后作为单独的订单传递给 Order
。 <router-link>
中的 ShowOrder
组件在其自己的页面上显示单个订单。
<template v-if="order ? order : error">
<div class="order-container -shadow">
<div class="order-number">
<p>{{ order.orderId }}</p>
<p>{{ order.daySelected }}</p>
<p>{{ order.timeSelected }}</p>
</div>
<div class="customer-info">
<h2>{{ order.userInfo.name }}</h2>
<p>
{{ order.userInfo.street }},
{{ order.userInfo.city }}
</p>
<p v-if="order.userInfo.apt">
{{ order.userInfo.apt }}
</p>
<p>{{ order.userInfo.phone }}</p>
...
...
<router-link :to="{ name: 'ShowOrder', params: { id: order.orderId, order: order }}"
>Show Details</router-link
>
</div>
</template>
<script>
export default {
name: "Order",
props: {
order: {
type: Object,
default: function() {
return {};
}
}
},
data() {
return {
error: "Error"
};
}
};
</script>
我的Order.spec.js
如下:
const localVue = createLocalVue();
localVue.use(VueRouter);
const router = new VueRouter();
const $route = {
path: '"/show-order/:id"'
};
shallowMount(Order, {
localVue,
router,
stubs: ["router-link", "router-view"]
});
const mockOrder = {
orderId: 123,
chocolateChip: 24,
oatmeal: 0,
campfire: 12,
daySelected: "Wed Jan 27",
timeSelected: "2:30 - 3:00",
userInfo: {
apt: "",
city: "Port ",
email: "k@gmail.com",
street: " Point Road",
phone: "(123)446-1980",
name: "Mr.Smith"
}
};
describe("Order.vue", () => {
it("renders correctly", () => {
const wrapper = shallowMount(Order, {
localVue,
propsData: {
order: mockOrder,
$route
}
});
console.log(wrapper.html());
expect(wrapper.element).toMatchSnapshot();
});
});
我收到的错误如下所示:
FAIL tests/unit/Order.spec.js
● Test suite failed to run
TypeError: Cannot read property 'name' of undefined
72 | flex-flow: column wrap;
73 | margin-top: 1em;
> 74 | transition: all 0.2s linear;
| ^
75 | }
76 |
77 | .order-container:hover {
我什至无法进行快照测试。我在这里阅读了许多其他类似的问题并出现此错误,并尝试在模板中使用 v-if
在组件加载之前等待数据。这里发生了什么?如果这是一个对象错误,为什么在控制台中有一个指向我的作用域 css 而不是 order.userInfo.name
的指针?
我也试过从 Admin.vue
中的 created()
更改为 mounted()
。
在 Order.vue
中,我尝试添加对象以使其基于这些 Vue docs.
data() {
return {
error: "Error",
orderItem: {}
};
},
mounted() {
this.orderItem = Object.assign({}, this.order);
console.log(this.orderItem, "line 65");
}
您调用了 shallowMount()
两次:一次是在没有 mockOrder
的情况下在测试之外(并且没有必要进行此调用),另一次是在测试内部使用 mockOrder
。
// Order.spec.js
shallowMount(Order, { localVue }) // ❌ no props, but no need for this call
describe("Order.vue", () => {
shallowMount(Order, {
localVue,
propsData: {
order: mockOrder
}
})
})
第一次调用导致错误,因为它的 order
属性默认为空对象,因此 order.userInfo
将是 undefined
,导致 order.userInfo.name
的错误.
解决方案是删除不必要的第一次调用 shallowMount()
。