championswimmer / vuex-module-decorators

TypeScript/ES7 Decorators to create Vuex modules declaratively
https://championswimmer.in/vuex-module-decorators/
MIT License
1.8k stars 170 forks source link

TypeError: Cannot read property 'getters' of undefined #63

Open farzadmf opened 5 years ago

farzadmf commented 5 years ago

Hi,

I'm facing an issue here with TypeScript when I want to unit test my module.

My index.ts for my store:

import { StoreOptions } from 'vuex';
import { EndUsersModule } from './end-user-module';

const store: StoreOptions<{}> = {
  modules: {
    endUsers: EndUsersModule,
  },
};

My end-user-module.ts:

import { Action, Module, Mutation, VuexModule } from 'vuex-module-decorators';
import { EndUser } from './models';
import store from '@/shared/store'

@Module({
  dynamic: true,
  name: 'endUsers',
  store,
})
export class EndUsersModule extends VuexModule {
  private users: EndUser[] = [];

  public get endUsers() {
    return this.users;
  }

  @Action
  public async createEndUser(user: EndUser) {
    this.context.commit('createUserStart');

    try {
      await api.createUser(user);
      this.context.commit('createUserSuccess', user);
    } catch (err) {
      this.context.commit('createUserFail', err);
    }
  }

  @Mutation
  public createEndUserFail(err: any)         { /* implementation */ }
  @Mutation
  public createEndUserStart()                { /* implementation */ }
  @Mutation
  public createEndUserSuccess(user: EndUser) { /* implementation */ }
}

Now, I want to test the action createEndUser, but my problem is that when I do this at the top of my file:

import { EndUsersModule } from './end-user-module';
import { createModule } from 'vuex-module-decorators';

const endUsers = getModule(EndUsersModule);

describe('...', () => {
  // ...
});

And run my tests, I see the following error message:

TypeError: Cannot read property 'getters' of undefined

Can you please tell me how I can unit test my actions, or the whole module for that matter?

I was also trying to do it with vuex-class, but that also has its complications for actions. Then, I found your library, and I thought everything should be fine now, but that's not the case :(

championswimmer commented 5 years ago

Check how the unit tests for actions runs in this very repository.

Every functionality has an unit test here.

On Wed 5 Dec, 2018, 9:17 AM Farzad Majidfayyaz <notifications@github.com wrote:

Hi,

I'm facing an issue here with TypeScript when I want to unit test my module.

My index.ts for my store:

import { StoreOptions } from 'vuex';import { EndUsersModule } from './end-user-module'; const store: StoreOptions<{}> = { modules: { endUsers: EndUsersModule, }, };

My end-user-module.ts:

import { Action, Module, Mutation, VuexModule } from 'vuex-module-decorators';import { EndUser } from './models';import store from '@/shared/store'

@Module({ dynamic: true, name: 'endUsers', store, })export class EndUsersModule extends VuexModule { private users: EndUser[] = [];

public get endUsers() { return this.users; }

@Action public async createEndUser(user: EndUser) { this.context.commit('createUserStart');

try {
  await api.createUser(user);
  this.context.commit('createUserSuccess', user);
} catch (err) {
  this.context.commit('createUserFail', err);
}

}

@Mutation public createEndUserFail(err: any) { / implementation / } @Mutation public createEndUserStart() { / implementation / } @Mutation public createEndUserSuccess(user: EndUser) { / implementation / } }

Now, I want to test the action createEndUser, but my problem is that when I do this at the top of my file:

import { EndUsersModule } from './end-user-module';import { createModule } from 'vuex-module-decorators'; const endUsers = getModule(EndUsersModule); describe('...', () => { // ... });

And run my tests, I see the following error message:

TypeError: Cannot read property 'getters' of undefined

Can you please tell me how I can unit test my actions, or the whole module for that matter?

I was also trying to do it with vuex-class https://github.com/ktsn/vuex-class, but that also has its complications for actions. Then, I found your library, and I thought everything should be fine now, but that's not the case :(

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/championswimmer/vuex-module-decorators/issues/63, or mute the thread https://github.com/notifications/unsubscribe-auth/ABQ_yiIgWLJMMYTrUq39uU-_QvUWC_0Wks5u10HMgaJpZM4ZB9An .

farzadmf commented 5 years ago

Thank you @championswimmer for your reply, I took a quick look at the tests, and it seems to me that to test, you're not using getModule function. Why is it different? I mean, looking at the documentation, I see that to use the module in our component, we're calling getModule, so, for that reason, I thought that in our tests, we should also need to call getModule

championswimmer commented 5 years ago

All getModule tests are here https://github.com/championswimmer/vuex-module-decorators/tree/master/test/getmodule

farzadmf commented 5 years ago

Also, I think it would be a good idea if a simple and small example application is provided in the repository to make things more clear

championswimmer commented 5 years ago

There are a couple of applications using vuex-module-decorators linked in the README

On Wed, 5 Dec 2018 at 19:06, Farzad Majidfayyaz notifications@github.com wrote:

Also, I think it would be a good idea if a simple and small example application is provided in the repository to make things more clear

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/championswimmer/vuex-module-decorators/issues/63#issuecomment-444487194, or mute the thread https://github.com/notifications/unsubscribe-auth/ABQ_ymxPYwUO6xRmAusA9mDsiOcFwz3jks5u18vSgaJpZM4ZB9An .

farzadmf commented 5 years ago

Yes, you're right, but personally I think it would help if an actual and working application is available to use as a reference. Examples are given in the README, but you can't see the general structure of the application (files etc), and how to glue everything together.

Of course it's just a suggestion for improvement that I think would help the users. I've been trying to make it work since yesterday, but I wasn't able to, and now I'm getting another error TypeError: Cannot read property 'registerModule' of undefined, so something is undefined somewhere, but I have no idea what it is. If I could compare what I'm doing to a reference application, I personally think that would be useful

championswimmer commented 5 years ago

I mean these my friend,

image

These are actual projects

farzadmf commented 5 years ago

Thank you @championswimmer , I had seen those before, but I had forgotten about them. Also, interestingly enough, none of those seems to have unit tests for their store!

Also, another question is that when they use getModule, they're passing <module>.prototype, but in the docs, it says something like getModule(MyModule), which one is correct?

UPDATE: it seems that they're using an older version of vuex-module-decorators, and for me, using prototype doesn't work

farzadmf commented 5 years ago

Hi again @championswimmer ! I think I'm making some progress here (thanks to the links you provided).

Two questions:



Is there a better and more concise way to do this?
bernhardwaidacher commented 5 years ago

I had the same issue. I resolved it by using this as store.ts


import Vue from 'vue';
import Vuex from 'vuex';
import UserStore from '@/stores/user-store';

Vue.use(Vuex);

interface StoreType {
  UserStore: UserStore
}

export default new Vuex.Store<StoreType>({})
stemann commented 5 years ago

It seems there are a lot of (failed) attempts at unit testing store modules, i.e. #126, #139 - in addition to this issue.

Could someone provide a complete example of how to write tests for a (dynamic) store module?

Here is my failed attempt - only successful attempt at getting a clean store for each (independent) test - is manually resetting the state via a mutation in beforeEach below.

I have tried:

'@/stores/index.ts':

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
});

'@/stores/AuthorizationStore.ts':

import { Module, VuexModule, Mutation } from 'vuex-module-decorators';
import store from '@/stores';

@Module({
    dynamic: true,
    store,
    name: 'authorization',
    namespaced: true,
    stateFactory: true
})
export class AuthorizationStore extends VuexModule {
    public authorizations: [] = [];

    @Mutation
    public setAuthorizations(authorizations: []) {
        this.authorizations = authorizations;
    }
}

'@/tests/unit/AuthorizationStore.spec.ts':

import { getModule } from 'vuex-module-decorators';
import { AuthorizationStore } from '@/stores/AuthorizationStore';

describe('authorization store', () => {
    let authorizationStore: AuthorizationStore;

    beforeEach(() => {
        authorizationStore = getModule(AuthorizationStore);
        // authorizationStore.setAuthorizations([]);
    });

    // This test passes
    it('pollute state', async () => {
        authorizationStore.setAuthorizations([42]);

        expect(authorizationStore.authorizations).toEqual([42]);
    });

    // This test fails unless manual mutation is applied in beforeEach
    it('construction yields initialized state', () => {
        expect(authorizationStore.authorizations).toEqual([]);
    });
});
Pita commented 4 years ago

I just ran into this as well. Seems like there is no example on the internet on how to successfully unit test while using vuex-module-decorators.

championswimmer commented 4 years ago

This entire project itself is fully unit tested. 🤷‍♂️

On Thu, 14 Nov, 2019, 6:16 PM Pita, notifications@github.com wrote:

I just ran into this as well. Seems like there is no example on the internet on how to successfully unit test while using vuex-module-decorators.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/championswimmer/vuex-module-decorators/issues/63?email_source=notifications&email_token=AAKD7SU7A4UYOI5F4GNYYL3QTVCD3A5CNFSM4GIH2AT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEBWZ6I#issuecomment-553872633, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAKD7SUJRPWXPM65JKOSAP3QTVCD3ANCNFSM4GIH2ATQ .

aislanmaia commented 4 years ago

@championswimmer man, I think what we really need is some examples testing component + the store modules. Preference for dynamic things, because, for somehow, they seems more complicated to integrate, I don't know.

Do you have some examples for this unit tests, please?

aislanmaia commented 4 years ago

I just want to test these fields for State, Getters, Mutations, Actions into a container component.

image

What I've seen in this repository is just tests for the store itself. :disappointed:

aislanmaia commented 4 years ago

I mean these my friend,

image

These are actual projects

These example repos even don't have real tests scenario, my friend. Take a look yourself.

viT-1 commented 4 years ago

I mean these my friend,

image

These are actual projects

https://github.com/Armour/vue-typescript-admin-template/tree/master/tests/unit https://github.com/xieguangcai/vue-order-admin/tree/master/tests/e2e/specs https://github.com/coding-blocks-archives/realworld-vue-typescript/tree/master/tests has no tests avout store

niconj commented 4 years ago

Hello @championswimmer is there any project that we can check how the testing was implemented? Neither of the already provided projects has any test that explains how to tackle this problem.

Please, is there somewhere where we can check it? Thanks in advance for your help so far!