Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errorenous state error during async testing #2137

Open
tylfin opened this issue Feb 22, 2022 · 4 comments
Open

Errorenous state error during async testing #2137

tylfin opened this issue Feb 22, 2022 · 4 comments

Comments

@tylfin
Copy link

tylfin commented Feb 22, 2022

Version

4.0.2

Steps to reproduce

For whatever reason, we're only able to reproduce this error in a Docker container, but our test suite raises this error:

Error: [vuex] do not mutate vuex store state outside mutation handlers.

Following the traceback, it points to an async action in an HTTP module:

const mutations = {
  [types.SET_GETTING_METRICS_STATUS](state, flag) {
    state.gettingMetricsStatus = flag;
  },
  [OMITTED]
}

const module = (HTTP) => ({
  state: defaultState,
  mutations,
  actions: {
    async getStatus({ commit }) {
      try {
        commit(types.SET_GETTING_METRICS_STATUS, true);
       [OMITTED]

Complaining that the SET_GETTING_METRICS_STATUS mutation is attempting to mutate state outside of mutation handlers.

Our test case is fairly simple as well, e.g.:

it("should update state correctly", async () => {
    const store = createStore(status.module(HTTP));

    const stub = sinon.stub(HTTP, "get");
    stub.onCall(0).returns({
    data: {
        [OMITTED]
    });

    expect(store.state).to.deep.equal(defaultState);

    await store.dispatch("getStatus");
    [OMITTED]

What is expected?

The test case should finish without error.

What is actually happening?

Vuex is incorrectly stating that the mutation is attempting to mutate state outside of a mutation.

@Akryum
Copy link
Member

Akryum commented May 4, 2022

Seeing this too happen in one of our test using Cypress component testing

@Akryum
Copy link
Member

Akryum commented May 4, 2022

It seems to happen if there is another store created somewhere in the code (although not used in the app).

@tylfin
Copy link
Author

tylfin commented May 5, 2022

@Akryum Ah sorry I should've updated this issue, but that's exactly what I found too. We had a store being created by default outside of any function in App.js, and a mock-store being created by our test.

I tried to trace through the Vue/Vuex code, but couldn't find the culprit given it's designed around creating multiple stores. We ended up making our global store creation lazy and only initialized when the actual app is started 🤷

If someone has time to look, I would first investigate the possibility of namespace collisions

@lisilinhart
Copy link

For me it helped to make a deep clone on the mock store configuration like described in the Vuex docs:
https://v1.test-utils.vuejs.org/guides/using-with-vuex.html#testing-a-running-store

import { cloneDeep } from 'lodash'

test('increments "count" value when "increment" is committed', () => {
  const localVue = createLocalVue()
  localVue.use(Vuex)
  const store = new Vuex.Store(cloneDeep(storeConfig))
  expect(store.state.count).toBe(0)
  store.commit('increment')
  expect(store.state.count).toBe(1)
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants