0
votes

My component's template contains the following element:

<v-text-field v-model="user.first_name" />

In my vuex store I declare a state

state: {
  user: { first_name: '' }
}

and a getter

getUserInfo(state) {
  return state.user;
}

My component on created() does the following:

this.user = { ...this.$store.getters.getUserInfo };

this.user is declared like so:

private user!: User;

In the test for this component I use beforeEach to mock the store:

beforeEach(() => {
    vuetify = new Vuetify();
    getters = {
        getUserInfo: () => ({ first_name: 'Test' })
    }
    store = new Vuex.Store({
        getters,
        state: {
            user: { first_name: 'Test' }
        }
    });
});

This should call the mocked getter on component created() and set the input value to 'Test' via the v-model.

console.log(wrapper.find('v-text-field-stub').text());

Returns an empty string. I'm reading there are lots of problems with vue-testing-utils and vuetify. (indeed I couldn't find a way to select the raw input element corresponding to the text-field)

To debug further, I tried displaying wrapper.vm.$data

class_property_1: [Getter/Setter],
class_property_2: [Getter/Setter],

but nothing about my user.

The test:

it('shows input with text', () => {
    const wrapper = shallowMount(MyComponent, {
        mocks: {
            $store: store
        },
        localVue,
        vuetify
    });
    console.log(wrapper.vm.$data);
    expect(wrapper.vm.$data.user.first_name).toBeTruthy(); // user is undefined
});

Do I need to explicitly call the getter in my test although it's called inside created()?

I tried making the getter getUserInfo() return a different string than 'Test' but

console.log(store.state.user.first_name);

still returns 'Test'

EDIT:

Using mount instead of shallowMount solves the text-field problem.

However console.log(wrapper.find('input').text()); is still empty

1
Replace mocks: { $store: store },... with simply store,.... It's already mocked and it shouldn't be bound to $store, but to store, just like in main.(js|ts).tao

1 Answers

1
votes

Seems like you may have some problems with your getter. Try something more like this:

beforeEach(() => {
    const vuetify = new Vuetify();
    const getters = {
        getUserInfo: (state) => state.user.first_name
    }
     const store = new Vuex.Store({
        getters,
        state: {
            user: { first_name: 'Test' }
        }
    });
});

Basicly it looks like your code for getters isn't getting a value, but instead trying to set it. Also, you aren't declaring your vars for vuetify or getters correctly inside that enclosure. JS is loosely type, so it might let you get away with it, but you might get some results you don't expect or at the very least not pass a linter.