Closed viT-1 closed 4 years ago
Cutted jest code:
import { createLocalVue, mount } from '@vue/test-utils';
import Vuex from 'vuex';
import { createDirectStore } from 'direct-vuex';
import { modSomeForm } from './store';
import { SomeForm } from './index'; // with vue-class-component decorated
const localVue = createLocalVue();
localVue.use(Vuex);
const storeConf = {
modules: {
modSomeForm,
},
};
const { store } = createDirectStore(storeConf);
describe('@Component SomeForm', () => {
it('all mock data are rendered', () => {
expect.assertions(1);
const wrapper = mount(SomeForm, { store, localVue });
wrapper.vm.$nextTick();
expect(...).toBe(true);
});
});
Just updated config to see problem directly:
npm run test
Maybe:
const wrapper = mount(SomeForm, { store: store.original, localVue });
This fix is helped, now I got another error (test suite is still failed to run):
TypeError: Cannot read property 'getters' of undefined
...
at forEachValue (../node_modules/vuex/dist/vuex.common.js:80:20)
at ModuleCollection.register (../node_modules/vuex/dist/vuex.common.js:210:5)
at new ModuleCollection (../node_modules/vuex/dist/vuex.common.js:171:8)
at new Store (../node_modules/vuex/dist/vuex.common.js:322:19)
at createDirectStore (../node_modules/direct-vuex/dist/direct-vuex.umd.js:17:24)
at Object.<anonymous> (VueApp/store/VueApp.store.ts:19:47)
Strange, but in VueApp.store.ts (which is seems not used in SomeForm.spec.ts)
export const { store, moduleActionContext } = createDirectStore(storeConf);
May be it is because of using standard Vuex getters, not createGetters.
Similar issue: https://github.com/championswimmer/vuex-module-decorators/issues/63
Also another test suite (SomeForm/store/actions.spec.ts) failed to run:
src/unique.blocks/SomeForm/store/actions.spec.ts:13:31 - error TS2345: Argument of type '{ dispatch: jest.Mock<any, any>; }' is not assignable to parameter of type 'ActionContext<IState, IState>'.
Type '{ dispatch: Mock<any, any>; }' is missing the following properties from type 'ActionContext<IState, IState>': commit, state, getters, rootState, rootGetters
13 await actions.getSomeValues({ dispatch }, { label: 'Рим' });
It seems context parameter in test (or actions) code should be changed but I don't understand how? On classic Vuex In actions I am using destructuring input parameter, but now I am using ActionContext from 'vuex'.
Can't find any example of using direct-vuex actions with tests =(
About getters same error. Fixed this in jest.config.js, for example:
moduleNameMapper: {
// special fix (not included in tsconfig.paths.json) for Vue warning about version of Vue
'vue$': 'vue/dist/vue.common.dev.js',
// fix for 'getters' error https://github.com/vuejs/vuex/issues/264#issuecomment-23694847
'vue': 'vue/dist/vue.js',
},
After fix I have another errors, investigating...
I have located problem with direct-vuex: Configured jest test with createDirectStore:
const storeConf = {
modules: {
modSomeForm,
},
};
const { store: _store } = createDirectStore(storeConf);
const store = _store.original;
...
const wrapper = mount(SomeForm, { store, localVue });
If I use classic actions, all is ok: SomeForm.spec.ts suite is runned & actions.spec.ts is runned. If I change actions.ts to using direct-vuex (just uncomment lines 3, 6, 12, 22, 23 & comment 24, 25) I have a problem with getters error (SomeForm.spec.ts suite is failed to run), but actions.spec.ts is ok - test suite is runned & passed.
@paleo please check this by cloning project & npm run test
When I execute npm run test
:
> tsc --project ./src/tsconfig.dev.json --noEmit && eslint **/*.{ts,json,js} *.* .*.js
Oops! Something went wrong! :(
ESLint: 6.8.0.
No files matching the pattern "express.node" were found.
Please check for typing mistakes in the pattern.
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! systemjs-ts-es6-vue@0.6.0 lint: `tsc --project ./src/tsconfig.dev.json --noEmit && eslint **/*.{ts,json,js} *.* .*.js`
npm ERR! Exit status 2
Is it the error I should see or another? (On Node 12.)
Strange, you can remove lint from pretest by renaming in package.json scripts "pretest" to "pre-something-test".
Is it the error I should see or another?
No, you should see
jest --no-cache --silent -c ./src/jest.config.js
PASS src/unique.blocks/SomeForm/store/mutations.spec.ts
...
PASS src/unique.blocks/SomeForm/store/actions.spec.ts
...
PASS src/unique.blocks/SomeForm/SomeForm.spec.ts
and after commening / commenting out in actions, you should see
jest --no-cache --silent -c ./src/jest.config.js
PASS src/unique.blocks/SomeForm/store/mutations.spec.ts
...
PASS src/unique.blocks/SomeForm/store/actions.spec.ts
...
FAIL src/unique.blocks/SomeForm/SomeForm.spec.ts
@paleo, 'getters' problem looks like code trying to get getters from root store instead of module substore.
I see only one workaround: using mocks with classic Vuex for actions in test suites & direct-vuex actions for browser & type checking.
Fyi, in this code:
export const storeConf = {
namespaced: true as true,
actions: createActions(actions),
// getters: createGetters<IState>()(getters),
getters,
mutations: createMutations<IState>()(mutations),
state: defaultState,
// syntax recommendation https://itnext.io/use-a-vuex-store-with-typing-in-typescript-without-decorators-or-boilerplate-57732d175ff3
// but we declare type with const above
// state: defaultState as IState,
} as const;
export const modSomeForm = createModule(storeConf);
… createModule
, createActions
, createMutations
are useless.
These functions provides autocompletion and typing in the implementation passed as a parameter. But if you declare first a variable then you pass it in these functions, they provide nothing.
Additionally, storeConf
and modSomeForm
are exactly the same object with the same typing.
If I use classic actions, all is ok: SomeForm.spec.ts suite is runned & actions.spec.ts is runned. If I change actions.ts to using direct-vuex (just uncomment lines 3, 6, 12, 22, 23 & comment 24, 25) I have a problem with getters error (SomeForm.spec.ts suite is failed to run), but actions.spec.ts is ok - test suite is runned & passed.
I reproduced the error. But your code is complex and I haven't enough time to understand. Maybe the error is an effect of the cyclic dependency because of moduleActionContext
. In your unit tests it is necessary to imports the files in the same order than during a regular execution of the project.
I have some fixes (not committed yet, it will be soon).
It is ready https://github.com/viT-1/systemjs-ts-es6-vue/commit/7ce884aa3bf4230e935c5dfdbfe778e302f09f2a For getting error about 'getters' now comment line 14 with mocking actions is enough.
Hi. Maybe localGetterContext
and localActionContext
could help. If you don't need to access to rootXxx
from action contexts, then localActionContext
should help avoiding the circular dependency.
@paleo Thank you, I'll try that. And If I can test actions without mocking, I'll closing the issue.
@paleo Yes, it's working.
In actions.ts just changed to
import { localActionContext } from 'direct-vuex';
const getTypedContext = (ctx: any) => localActionContext(ctx, modSomeForm);
instead of
import { moduleActionContext } from '~/VueApp/store';
const getTypedContext = (ctx: any) => moduleActionContext(ctx, modSomeForm);
And I can remove standard actions mocking!
With node (jest)
const getTypedContext = (ctx: any) => localActionContext(ctx, modSomeForm);
is ok,
but with browser I have error:
Uncaught (in promise) TypeError: localActionContext is not a function
at getTypedContext (actions.ts:16)
at actions.ts:27
Indeed, I forgot to export these new functions as properties of default
.
Update and retry please.
v 0.10.4 esm bundle is working, but ie11 (with SystemJS) is not:
Unhandled promise rejection TypeError: Object is not support property or method "localActionContext"
You can try my project on last commit npm run deploy
&& npm run www
@paleo, default
is good but i configured named imports too (in VueApp.store.ts)
Just update in importmap.system.json
. The tools you use are very weird.
@paleo Sorry for wasting your time, thank you very much! Just changed importmap.system.json in my project & all working is ok.
I changed my code to use direct-vuex in actions, browser seems to work without errors, but when I run jest tests, test suite failed to run, cause of typing when I mount component with store
What am I doing wrong?