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()