Модульное тестирование действия vuex в машинописи, как передать значение this? - PullRequest
0 голосов
/ 01 февраля 2020

Я использую Vuex в настройке машинописного текста и хочу провести модульное тестирование действия, но у меня возникают проблемы с установкой параметра this метода действия.

Действие выглядит примерно так:

export const login: ActionHandler<AuthState, RootState> = ({ commit },
  creds: { email: string, password: string }) => {
};

Тест выглядит следующим образом:

  describe('actions', () => {
    test('login should call api with credentials', () => {
      (ApiService.post as jest.Mock).mockResolvedValue({
        data: { userId: 1234 }
      });
      const commit = jest.fn();
      login({ commit }, { email: 'username@gmail.com', password: 'Pa$$w0rd123' });
    });
  });

Проблема в том, что ActionHandler имеет такую ​​подпись, как: login(this: Store<RootState>, injectee: ActionContext<AuthState, RootState>, payload?: any): any.

И TS выдает мне ошибку:

The 'this' context of type 'void' is not assignable to method's 'this' of type 'Store<RootState>'.ts(2684)

Я не могу понять, как установить экземпляр Store<RootState> в качестве this действия входа в систему. Я делаю это неправильно? Я понимаю, что эта проблема не возникнет, если я использую vanilla JS, но хотел бы продолжать использовать TS, если это возможно.

1 Ответ

0 голосов
/ 15 марта 2020

Я нашел два способа решения аналогичной проблемы. Пожалуйста, попробуйте.

1. Метод: Привязка this (рекомендуется)

Вам необходимо привязать свой store к this и использовать связанное действие:

// Bind
const loginBound = login.bind(store)

// Call
loginBound( /* ... */ );

Вам может потребоваться определить больше насмешек , чтобы это решение работало. См. «Приложение: полное кодовое решение» ниже.

2. Метод: Используйте Function cast

Используя этот подход, вы удовлетворите Typescript, но вы в некотором роде отметите проблему под ковриком (вы в основном отключаете проверки типов для действия).

// Bind
const loginCast = login as Function

// Call
loginCast( /* ... */ );

Приложение: решение с полным кодом

При использовании 1-го метода (привязка this) вам, вероятно, потребуется предоставить полный контекст действия. Все решение будет выглядеть так:

describe('actions', () => {
  test('login should call api with credentials', () => {
    (ApiService.post as jest.Mock).mockResolvedValue({
      data: { userId: 1234 }
    });

    // Bind `this`
    const loginBound = login.bind(store)

    // Provide full action context
    const actionContext: ActionContext<AuthState, RootState> = {
      dispatch: jest.fn(),
      commit: jest.fn(),
      state: {}, // here goes your auth state mock
      getters: {},
      rootState: {}, // here goes your root state mock
      rootGetters: {}
    };

    // Call
    loginBound(actionContext, { email: 'username@gmail.com', password: 'Pa$$w0rd123' });
  });
});
...