Skip to content

Proposal: Enhancement for testAction helper method #939

Closed
@kingstenbanh

Description

@kingstenbanh

What problem does this feature solve?

The current API for the testAction method helps reducing the need to stub out the action context (state, rootState, commit, etc). However, the recommended method assumes that each action will only trigger a state mutation (commit) and access previous data (state), which is not true in real-world and large-scale project. In my project, an action might need to dispatch another action, access the state of another module (rootState), or some getters. The current method doesn't give us the full access of the action context resulting in a lot of mocking in writing tests. I bet a lot of user out there are experiencing the same problem.

What does the proposed API look like?

The proposed API will create a similar signature with the way an action is created.

const actions = {
   [CREATE_USER](context, payload) {
      // do something here
   },
};

// original testAction
const testAction = (action, payload, state, expectedMutation, done) => {
  ...
};

// proposed testAction
const testAction = (action, context, payload, expectedMutations, done) => {
  ...
};

Here is the proposed testAction.

const testAction = (
    action,
    {
        state,
        rootState,
        getters,
    },
    payload,
    expectedMutations,
    done
) => {
    let count = 0;

    // mock commit
    const commit = (type, commitPayload) => {
        const mutation = expectedMutations[count];

        try {
            expect(mutation.type).to.equal(type);

            if (commitPayload) {
                expect(mutation.payload).to.deep.equal(commitPayload);
            }
        } catch (error) {
            done(error);
        }

        count  ;

        if (count >= expectedMutations.length) {
            done();
        }
    };

    // mock dispatch
    const dispatch = (type, dispatchPayload) => {
        const mutation = expectedMutations[count];

        try {
            expect(mutation.type).to.equal(type);

            if (dispatchPayload) {
                expect(mutation.payload).to.deep.equal(dispatchPayload);
            }
        } catch (error) {
            done(error);
        }

        count  ;

        if (count >= expectedMutations.length) {
            done();
        }
    };

    
    const context = {
        state,
        rootState,
        commit,
        dispatch,
        getters,
    };

    // call the action with mocked store and arguments
    action(context, payload);

    // check if no mutations should have been dispatched
    if (expectedMutations.length === 0) {
        expect(count).to.equal(0);
        done();
    }
};

export default testAction;

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions