Как мне протестировать этот довольно сложный React.Context - PullRequest
0 голосов
/ 08 января 2020

Я работаю над некоторым внешним кодом, и мы используем React useContext () вместо Redux. Раньше у нас все было в одном контексте, пока я не понял, что каждый элемент, подписанный на useContext, рендерит каждый раз, когда изменяется любое значение в контексте (в отличие от Redux, где вы можете просто подписаться на отдельные изменения в хранилище Redux с помощью используя mapStateToProps.)

Итак, чтобы решить эту проблему, я разбил монолитный c StateManager на несколько контекстов, но теперь мне сложно понять, как выполнить модульное тестирование контекстов.

У меня довольно сложный вопрос, который срабатывает на основе window.addEventListeners - но это тема для другого поста.

Как бы я протестировал этот код?

import React, { createContext, useReducer } from 'react';
import pick from 'lodash/pick';
import isEqual from 'lodash/isEqual';

export interface SocialManagerState {
  /* interface def goes here - not important */
} 

export const SocialManagerContext = createContext<SocialManagerState>({});
export const SocialManagerDispatchContext = createContext<any>({});

// basically just a shallow merge. 
const socialReducer = (
  state: SocialManagerState,
  action: Partial<SocialManagerState>
): SocialManagerState => {
  if (isEqual(pick(state, Object.keys(action)), action)) {
    return state;
  }
  return { ...state, ...action };
};

interface SocialManagerProviderProps {
  children: any;
  testOverride?: any; // this is only used in unit tests;
  [key: string]: any;
}
export const SocialManagerProvider: React.FC<SocialManagerProviderProps> = ({
  children,
  testOverride
}) => {
  const [socialValue, dispatchSocial] = useReducer(socialReducer, {});
  if (testOverride) {
    console.warn('Social Manager Provider values are being overwritten for test');
    dispatchSocial(testOverride);
  }
  return (
    <SocialManagerContext.Provider value={socialValue}>
      <SocialManagerDispatchContext.Provider value={dispatchSocial}>
        {children}
      </SocialManagerDispatchContext.Provider>
    </SocialManagerContext.Provider>
  );
};

export default SocialManagerContext;
...