Search code examples
vuejs2jestjsvue-test-utils

TypeError when rendering property of Vue-test setData object


I'm running into a strange situation and can't figure out why. Basically in my HTML, if I render 'actor[0]', the test runs fine and the console log shows the entire 'actor' object present in setData

However, if I try to access a property of the 'actor' object, like actor[0].firstname, the test throws a TypeError-can't-read-property-of-undefined.

The weird part is console logging 'wrapper.vm.actor[0].firstname' works fine so it doesn't seem like an async issue.

myapps.spec.js

import { mount } from "@vue/test-utils";
import MyApps from "@/pages/myapps.vue";
import Vuetify from "vuetify";

describe("Testing Myapps", () => {
  let vuetify;

  beforeEach(() => {
    vuetify = new Vuetify();
  });
  it("Checks SideBarComponent is rendered", async () => {
    const wrapper = mount(MyApps, {
      //   localVue,
      vuetify,
      mocks: {
        $vuetify: { breakpoint: {} }
      },
      stubs: {
        SideBarComponent: true,
        FooterComponent: true
      }
    });
    await wrapper.setData({
      actor: [
        {
          firstname: "bob",
          lastname: "bob",
          group: "actors"
        }
      ]
    });

    console.log(wrapper.html()); //  TypeError: Cannot read property 'first name' of undefined
    console.log(wrapper.vm.actor[0].firstname); // "bob" if I set the template back to actor[0] so the test runs


  });
});

myapps.vue

<template>
  <div>
    <v-app>
      <v-col cols="3">
        <v-btn
          text
          @click="getAcceptedApplications"
          elevation="0"
          block
        >Accepted {{actor[0].firstname}}</v-btn>
      </v-col>
    </v-app>
  </div>
</template>

<script>
export default {
 async asyncData({ params, $axios, store }) {
    try {
      const body = store.getters.loggedInUser.id;
      const [applications, actor] = await Promise.all([
        $axios.$get(`/api/v1/apps/`, {
          params: {
            user: body
          }
        }),
        $axios.$get(`/api/v1/actors/`, {
          params: {
            user: body
          }
        })
      ]);
      return { applications, actor };
      if (applications.length == 0) {
        const hasApps = false;
      }
    } catch (error) {
      if (error.response.status === 403) {
        const hasPermission = false;
        console.log(hasPermission, "perm");
        console.error(error);
        return { hasPermission };
      }
    }
  },
  data() {
    return {
      actor: []
    };
  }
};
</script>
          

Solution

  • Try not to use setData method, pass data while mounting the component like that:

    const wrapper = mount(MyApps, {
      vuetify,
      mocks: {
        $vuetify: { breakpoint: {} }
      },
      stubs: {
        SideBarComponent: true,
        FooterComponent: true
      }
      data: () => ({
        actor: [
           {
              firstname: "bob",
              lastname: "bob",
              group: "actors"
           }
        ]
      })
    })