8

I am writing unit tests for my vuejs components in a larger application. My application state is all in the vuex store, so almost all of my components pull data from vuex.

I can't find a working example for writing unit test for this. I have found

Where Evan You says:

When unit testing a component in isolation, you can inject a mocked store directly into the component using the store option.

But I can't find a good example of how to test these components. I have tried a bunch of ways. Below is the only way I have seen people do it. stackoverflow question and answer

Basically it looks like the

test.vue:

 <template>
    <div>test<div>
 </template>
 <script>
 <script>
    export default {
        name: 'test',
        computed: {
            name(){
                return this.$store.state.test;
            }
        }
    }
  </script>

test.spec.js

import ...

const store = new Vuex.Store({
  state: {
    test: 3
  }
});
describe('test.vue', () => {

  it('should get test from store', () => {

    const parent = new Vue({
      template: '<div><test ref="test"></test></div>',
      components: { test },
      store: store
    }).$mount();

    expect(parent.$refs.test.name).toBe(3);
  });
}

Note the "ref" this example doesn't work without it.

Is this really the right way to do this? It seems like it will get messy fast, because it requires adding the props into the template as a string.

Evan's quote seems to imply that the store can be added directly to the child component (ie not the parent like the example).

How do you do that?

Community
  • 1
  • 1
Patrick_Finucane
  • 725
  • 1
  • 7
  • 24
  • This method isn't working with bable-loader for js but does with buble loader for js. The error is always Error: [vuex] must call Vue.use(Vuex), even with the Vue.use(Vuex), with both import vue and with require vue. – Patrick_Finucane Apr 19 '17 at 23:25

1 Answers1

10

The answer is actually really straightforward but not currently documented.

  const propsData = { prop: { id: 1} };
  const store = new Vuex.Store({state, getters});

  const Constructor = Vue.extend(importedComponent);
  const component = new Constructor({ propsData, store });

Note the store passed to the constructor. propsData is currently documented, the "store" option isn't.

Also if you are using Laravel, there are weird problems with the webpack versions you may be running.

The

[vuex] must call Vue.use(Vuex),

Error was caused by useing laravel-elixir-webpack-official.
If you did the fix:

npm install webpack@2.1.0-beta.22 --save-dev

for this https://github.com/JeffreyWay/laravel-elixir-webpack-official/issues/17

Your tests that include Vuex seem to break with the

[vuex] must call Vue.use(Vuex)

even when you have Vue.use(Vuex)

tony19
  • 125,647
  • 18
  • 229
  • 307
Patrick_Finucane
  • 725
  • 1
  • 7
  • 24
  • This does appear to work but I'm a bit concerned that it relies on an undocumented aspect of the API. Does anyone have any info on weather this is supported or an alternate approach? – d512 Nov 13 '17 at 00:54