lmiller1990 / vue-testing-handbook

A guide on testing Vue components and applications
https://lmiller1990.github.io/vue-testing-handbook/
876 stars 160 forks source link

Sample Request: Component - Actions test sample with namespaced modules #111

Closed francescq closed 5 years ago

francescq commented 5 years ago

Hello,

I wish to test Vuex store actions in components. The guide provided is very good: https://github.com/lmiller1990/vue-testing-handbook/blob/master/src/vuex-in-components-mutations-and-actions.md

My problem is our Vuex store has a lot os namespaced modules, 50 aprox.

I cannot find the way to properly test the Component - Action connection without having the replicate the whole store namespace structure in the test, which makes it unmantainable.

Can someone provide light on this matter? add a namespaced module sample in https://github.com/lmiller1990/vue-testing-handbook/blob/master/src/vuex-in-components-mutations-and-actions.md?

Thanks a lot! Francesc

lmiller1990 commented 5 years ago

Hey @francescq ,

Sure, this should be relatively straight forward. I can work on this during this week. If you have a minimal component and Vuex module, I could use as a base for the example.

lmiller1990 commented 5 years ago

@francescq , is this along the lines of what you mean? https://github.com/lmiller1990/vue-testing-handbook/pull/112

Feel free to leave some comments on the PR, or let me know if you need help with anything else.

francescq commented 5 years ago

Yes @lmiller1990!

Thank you very much as it's the example I'm looking for. It shows how to test using a real Vuex store with a namespace module.

As in the example, the Vuex Store must be created with the namespace. Now imagine the app has lots of namespaced modules with 4 layers of nesting (I don't wont to know who decided that...)

As the store grows, the test become unmaintainable.

Is there any way to prevent to create the whole namespace structure for each test?

Ideally I would like to be able to inject from outside the store module I want the component to use in order to keep the component agnostic/decoupled of any module.

Is there any way to achieve that?

I wish I explained good enough the problem,

Thanks!

lmiller1990 commented 5 years ago

@francescq , I updated my example - you actually do not need to make the namespaced module at all in the example, since you mock the dispatch method entirely. Please see it again.

If you have something else in mind, please post an example component/store combo you are having trouble with and I can try and give you some ideas.

<template>
  <div>
    <button
      class="namespaced-dispatch"
      @click="handleNamespacedDispatch">
      Namespaced Dispatch
    </button>
  </div>
</template>

<script>
export default {
  name: "ComponentWithButtons",

  methods: {
    handleNamespacedDispatch() {
      this.$store.dispatch(
        "namespaced/very/deeply/testAction",
        { msg: "Test Namespaced Dispatch" }
      )
    }
  }
}
</script>

And:

  it("dispatch a namespaced action when button is clicked", () => {
    const store = new Vuex.Store()
    store.dispatch = jest.fn()

    const wrapper = shallowMount(ComponentWithButtons, {
      store, localVue
    })

    wrapper.find(".namespaced-dispatch").trigger("click")

    expect(store.dispatch).toHaveBeenCalledWith(
      'namespaced/very/deeply/testAction',
      { msg: "Test Namespaced Dispatch" }
    )
  })
francescq commented 5 years ago

Yes! That's the example I was looking for.

Still I don't think having the namespace inside the component is the most suitable decision yet at least, the test is clean and scalable which is good :)

Many many thanks!

lmiller1990 commented 5 years ago

Not sure what you mean by "the namespace inside the component" - you could consider moving "namespaced/very/deeply/testAction" to a constant file and importing it.

Seems like this helped you. I'll merge the PR and close this, let me know if you need anything else.

francescq commented 5 years ago

I mean the componen should be module agnostic. It should just use the injected module and that's it.

The higher component using our component should inject the module and non our component neither the test should be aware of any namespace.

With the helpers ..mapActions , mapGetters... and so on, vue logs a nice warning about the module not being found on test.

Missatge de Lachlan notifications@github.com del dia dc., 24 de jul. 2019 a les 0:25:

Not sure what you mean by "the namespace inside the component" - you could consider moving "namespaced/very/deeply/testAction" to a constant file and importing it.

Seems like this helped you. I'll merge the PR and close this, let me know if you need anything else.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/lmiller1990/vue-testing-handbook/issues/111?email_source=notifications&email_token=AARWDSTVHMKOGUBTEXOJV4DQA6APJA5CNFSM4IBOWTO2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2UTQAI#issuecomment-514406401, or mute the thread https://github.com/notifications/unsubscribe-auth/AARWDSV54LCCCCAQTR3NZO3QA6APJANCNFSM4IBOWTOQ .