diff options
author | Mark Florian <553096-markrian@users.noreply.gitlab.com> | 2019-06-25 18:44:20 +0300 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2019-06-25 18:44:20 +0300 |
commit | 4e05f89413c603ee56774afc91903cb1f31d0541 (patch) | |
tree | 882f226dee292ae7404c888ce1a235d2e9ab2d37 /spec/frontend | |
parent | be862af45184b1d9fbede1924d7a8c6395637b29 (diff) |
Move Vuex action helper spec to Jest
This is largely a straight-forward copy of the Karma spec, with the
usual Karma->Jest necessary changes.
This also fixes a bug in the implementation that was causing the tests
to fail, when run on Jest/node, whereby actions that return rejected
promises would always fail the given test. This was due to those
rejections not being caught in the same call stack in which they were
created.
Diffstat (limited to 'spec/frontend')
-rw-r--r-- | spec/frontend/helpers/vuex_action_helper.js | 7 | ||||
-rw-r--r-- | spec/frontend/helpers/vuex_action_helper_spec.js | 166 |
2 files changed, 168 insertions, 5 deletions
diff --git a/spec/frontend/helpers/vuex_action_helper.js b/spec/frontend/helpers/vuex_action_helper.js index 88652202a8e..6c3569a2247 100644 --- a/spec/frontend/helpers/vuex_action_helper.js +++ b/spec/frontend/helpers/vuex_action_helper.js @@ -20,7 +20,7 @@ const noop = () => {}; * // expected mutations * [ * { type: types.MUTATION} - * { type: types.MUTATION_1, payload: jasmine.any(Number)} + * { type: types.MUTATION_1, payload: expect.any(Number)} * ], * // expected actions * [ @@ -89,10 +89,7 @@ export default ( payload, ); - return new Promise(resolve => { - setImmediate(resolve); - }) - .then(() => result) + return (result || new Promise(resolve => setImmediate(resolve))) .catch(error => { validateResults(); throw error; diff --git a/spec/frontend/helpers/vuex_action_helper_spec.js b/spec/frontend/helpers/vuex_action_helper_spec.js new file mode 100644 index 00000000000..61d05762a04 --- /dev/null +++ b/spec/frontend/helpers/vuex_action_helper_spec.js @@ -0,0 +1,166 @@ +import MockAdapter from 'axios-mock-adapter'; +import { TEST_HOST } from 'helpers/test_constants'; +import axios from '~/lib/utils/axios_utils'; +import testAction from './vuex_action_helper'; + +describe('VueX test helper (testAction)', () => { + let originalExpect; + let assertion; + let mock; + const noop = () => {}; + + beforeEach(() => { + mock = new MockAdapter(axios); + /** + * In order to test the helper properly, we need to overwrite the Jest + * `expect` helper. We test that the testAction helper properly passes the + * dispatched actions/committed mutations to the Jest helper. + */ + originalExpect = expect; + assertion = null; + global.expect = actual => ({ + toEqual: () => { + originalExpect(actual).toEqual(assertion); + }, + }); + }); + + afterEach(() => { + mock.restore(); + global.expect = originalExpect; + }); + + it('properly passes state and payload to action', () => { + const exampleState = { FOO: 12, BAR: 3 }; + const examplePayload = { BAZ: 73, BIZ: 55 }; + + const action = ({ state }, payload) => { + originalExpect(state).toEqual(exampleState); + originalExpect(payload).toEqual(examplePayload); + }; + + assertion = { mutations: [], actions: [] }; + + testAction(action, examplePayload, exampleState); + }); + + describe('given a sync action', () => { + it('mocks committing mutations', () => { + const action = ({ commit }) => { + commit('MUTATION'); + }; + + assertion = { mutations: [{ type: 'MUTATION' }], actions: [] }; + + testAction(action, null, {}, assertion.mutations, assertion.actions, noop); + }); + + it('mocks dispatching actions', () => { + const action = ({ dispatch }) => { + dispatch('ACTION'); + }; + + assertion = { actions: [{ type: 'ACTION' }], mutations: [] }; + + testAction(action, null, {}, assertion.mutations, assertion.actions, noop); + }); + + it('works with done callback once finished', done => { + assertion = { mutations: [], actions: [] }; + + testAction(noop, null, {}, assertion.mutations, assertion.actions, done); + }); + + it('returns a promise', done => { + assertion = { mutations: [], actions: [] }; + + testAction(noop, null, {}, assertion.mutations, assertion.actions) + .then(done) + .catch(done.fail); + }); + }); + + describe('given an async action (returning a promise)', () => { + let lastError; + const data = { FOO: 'BAR' }; + + const asyncAction = ({ commit, dispatch }) => { + dispatch('ACTION'); + + return axios + .get(TEST_HOST) + .catch(error => { + commit('ERROR'); + lastError = error; + throw error; + }) + .then(() => { + commit('SUCCESS'); + return data; + }); + }; + + beforeEach(() => { + lastError = null; + }); + + it('works with done callback once finished', done => { + mock.onGet(TEST_HOST).replyOnce(200, 42); + + assertion = { mutations: [{ type: 'SUCCESS' }], actions: [{ type: 'ACTION' }] }; + + testAction(asyncAction, null, {}, assertion.mutations, assertion.actions, done); + }); + + it('returns original data of successful promise while checking actions/mutations', done => { + mock.onGet(TEST_HOST).replyOnce(200, 42); + + assertion = { mutations: [{ type: 'SUCCESS' }], actions: [{ type: 'ACTION' }] }; + + testAction(asyncAction, null, {}, assertion.mutations, assertion.actions) + .then(res => { + originalExpect(res).toEqual(data); + done(); + }) + .catch(done.fail); + }); + + it('returns original error of rejected promise while checking actions/mutations', done => { + mock.onGet(TEST_HOST).replyOnce(500, ''); + + assertion = { mutations: [{ type: 'ERROR' }], actions: [{ type: 'ACTION' }] }; + + testAction(asyncAction, null, {}, assertion.mutations, assertion.actions) + .then(done.fail) + .catch(error => { + originalExpect(error).toBe(lastError); + done(); + }); + }); + }); + + it('works with async actions not returning promises', done => { + const data = { FOO: 'BAR' }; + + const asyncAction = ({ commit, dispatch }) => { + dispatch('ACTION'); + + axios + .get(TEST_HOST) + .then(() => { + commit('SUCCESS'); + return data; + }) + .catch(error => { + commit('ERROR'); + throw error; + }); + }; + + mock.onGet(TEST_HOST).replyOnce(200, 42); + + assertion = { mutations: [{ type: 'SUCCESS' }], actions: [{ type: 'ACTION' }] }; + + testAction(asyncAction, null, {}, assertion.mutations, assertion.actions, done); + }); +}); |