Repository: ktsn/vuex-smart-module (ts)

Issue:
Jest TS: mocking mutations in actions fails
Hello,

I am writing some Jest tests for a store module written with `vuex-smart-modules@0.4.2`. I've encountered a problem when testing actions that call a mutation via the `this.mutations` property. 

VSCode reports a `No overload matches this call.` error when trying to inject a `mutations` property in the `inject` function. 

Here is an example code:

```ts
import { Mutations, Actions, Getters, inject } from 'vuex-smart-module';

class DemoState {
  str = 'hello';
}

class DemoMutations extends Mutations<DemoState> {
  update(str: string) {
    this.state.str = str;
  }
}

class DemoActions extends Actions<
  DemoState,
  Getters<DemoState>,
  DemoMutations,
  DemoActions
> {
  update(payload: string) {
    this.mutations.update(payload);
  }
}

test('action update', () => {
  const update = jest.fn();
  const actions = inject(DemoActions, { // <-- ERROR HERE
    state: new DemoState(),
    mutations: {
      update,
    },
  });

  actions.update('world');
  expect(update).toHaveBeenCalledWith('world');
});

```

The error seems to bother just the TS checker, because Jest tests do not fail.

Any hint on how to solve the issue?

Pull request:
fix: allow mocking `mutations` and `actions` in an action test
fix #255 

Patch:
diff --git a/src/assets.ts b/src/assets.ts
index b59b9f5..b780972 100644
--- a/src/assets.ts
+++ b/src/assets.ts
@@ -17,16 +17,31 @@ export function inject<G extends Getters<S>, S>(
   Getters: Class<G>,
   injection: DeepPartial<G & { state: S; getters: G }>
 ): G
+
 export function inject<M extends Mutations<S>, S>(
   Mutations: Class<M>,
   injection: DeepPartial<M & { state: S }>
 ): M
-export function inject<A extends Actions<S, G, any, any>, S, G extends BG<S>>(
+
+export function inject<
+  A extends Actions<S, G, M, A>,
+  S,
+  G extends BG<S>,
+  M extends BM<S>
+>(
   Actions: Class<A>,
   injection: DeepPartial<
-    A & { state: S; getters: G; dispatch: any; commit: any }
+    A & {
+      state: S
+      getters: G
+      dispatch: any
+      commit: any
+      mutations: M
+      actions: A
+    }
   >
 ): A
+
 export function inject<T>(
   F: Class<T>,
   injection: DeepPartial<T> & Record<string, any>


Test patch:
diff --git a/test/testability.spec.ts b/test/testability.spec.ts
index 48127e0..31e4dd5 100644
--- a/test/testability.spec.ts
+++ b/test/testability.spec.ts
@@ -28,6 +28,14 @@ class TestActions extends Actions<
   inc() {
     this.commit('inc', undefined)
   }
+
+  incBypass() {
+    this.actions.inc()
+  }
+
+  incCall() {
+    this.mutations.inc()
+  }
 }
 
 const test = new Module({
@@ -79,13 +87,34 @@ describe('testability', () => {
     expect(state.count).toBe(11)
   })
 
-  it('tests actions', (done) => {
+  it('tests actions', () => {
+    const commit = jest.fn()
     const actions = inject(TestActions, {
-      commit(type: string) {
-        expect(type).toBe('inc')
-        done()
-      },
+      commit,
     })
     actions.inc()
+    expect(commit).toHaveBeenCalledWith('inc', undefined)
+  })
+
+  it('mocks actions in an action', () => {
+    const inc = jest.fn()
+    const actions = inject(TestActions, {
+      actions: {
+        inc,
+      },
+    })
+    actions.incBypass()
+    expect(inc).toHaveBeenCalled()
+  })
+
+  it('mocks mutations in an action', () => {
+    const inc = jest.fn()
+    const actions = inject(TestActions, {
+      mutations: {
+        inc,
+      },
+    })
+    actions.incCall()
+    expect(inc).toHaveBeenCalled()
   })
 })