0

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>
          
4
  • Could you provide the code of your component? Commented Jul 20, 2021 at 11:56
  • @Eduardo Hi, yeah I've updated it with the local data store. There's more to the component, but this is the only part of the template which uses the 'actor' variable. Commented Jul 21, 2021 at 0:17
  • Strange, I checked the code, seems like everything should work. How actually actor array is being set in the component? You didn't include that part of the code. Commented Jul 21, 2021 at 6:12
  • The component itself has 'actor' set when the initial Axios call is made in asyncData. I added that part now. It works fine when being set that way, so I'm thinking it has something to do with how setData() is working in the test. Commented Jul 21, 2021 at 15:08

1 Answer 1

1

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"
       }
    ]
  })
})
Sign up to request clarification or add additional context in comments.

2 Comments

Huh that worked! I had to change data from arrow function to a normal one that returns actor though. I'm guessing that setData causes an error since it's meant to be called after mounting?
Glad the code helped! I don't know about causing errors but when I saw asyncData call I remembered how I tested my Nuxt app and then just shared the approach I used :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.