反应测试的模拟上下文

时间:2021-03-15 18:51:30

标签: javascript reactjs jestjs react-testing-library react-context

所以我有这个上下文:

import React, { useState, createContext } from 'react';
import { AuthState } from '../types/auth-state.type';

const initialState = {
  isAuthenticated: false,
  profile: null,
  socket: null,
};

export interface IAuthContext {
  authState: AuthState;
  setAuthState: React.Dispatch<AuthState>;
}

export const AuthContext = createContext<IAuthContext>({
  authState: initialState,
  setAuthState: () => {},
});

function AuthContextProvider(props: any) {
  const [authState, setAuthState] = useState<AuthState>(initialState);
  return <AuthContext.Provider value={{ authState, setAuthState }}>{props.children}</AuthContext.Provider>;
}
export default AuthContextProvider;

连同这个组件:

export const SelectedClientWrapper = ({ children }: ISelectedClientWrapper) => {
  const { authState, setAuthState } = useContext(AuthContext);
  const { clientsState } = useContext(ClientsContext);
  const [cachedClientId, setCachedClientId] = useState<string>('');

  useMountEffect(() => {
    getCachedSelectedClient().then((r) => {
      setCachedClientId(r);
    });
  });

  console.log('profile', authState.profile);
  if (!authState.profile) {
    console.log(2);
    const selectedClient = clientsState.clients.find((client) => client.client_id === cachedClientId);
    console.log({ selectedClient });
    if (selectedClient) {
      console.log(3);
      setAuthState({ ...authState, profile: selectedClient });
      setCachedClientId('');
    }
  }
  return children;
};

这是我的测试:

export const authenticatedInitial = {
  authState: {
    isAuthenticated: true,
    profile: null,
    socket: null,
  },
  setAuthState: () => {},
};
export const clientsMultipleClientsInitial = {
  clientsState: {
    isFetching: false,
    clients: mockClientsProfiles,
    profileToGreet: mockClientsProfiles[0],
    hasMultipleClients: true,
  },
  setClientsState: () => {},
};
export const MockAuthContext = ({ initialValue, children }: IMockAuthContext) => {
  return <AuthContext.Provider value={initialValue}>{children}</AuthContext.Provider>;
};

const renderComponent = (
  { initialAuthValue = authenticatedInitial, initialClientsValue = clientsMultipleClientsInitial }: IRenderComponent = {
    initialAuthValue: authenticatedInitial,
    initialClientsValue: clientsMultipleClientsInitial,
  }
): RenderResult =>
  render(
    <MockAuthContext initialValue={initialAuthValue}>
      <MockClientsContext initialValue={initialClientsValue}>
        <MockRouterWrapper>
          <SelectedClientWrapper>
            <I18nextWrapper>
              <Route path={RoutesEnum.clients}>
                <div>clients</div>
              </Route>
              <Route path={RoutesEnum.stake}>
                <div>stake</div>
              </Route>
            </I18nextWrapper>
          </SelectedClientWrapper>
        </MockRouterWrapper>
      </MockClientsContext>
    </MockAuthContext>
  );

所以这一切看起来都不错,也很有意义。

组件的逻辑是:

如果 auth.profile 未设置,则查找可能被缓存的客户端。如果他被缓存,请将其设置为配置文件,并清除状态(这可以防止站点卡在一个客户端上,异步等等)。否则就返回孩子。

当我手动测试时它有效。问题是,当我尝试模拟它时,它不会更新上下文,因此它执行所有魔术,找到用户,在最后一个 if 中运行代码,但上下文未更新,因此它重定向到错误的路线。所以在日志中我得到:

  console.log
    profile null

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:21:11)

  console.log
    2

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:23:13)

  console.log
    { selectedClient: undefined }

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:25:13)

  console.log
    profile null

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:21:11)

  console.log
    2

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:23:13)

  console.log
    {
      selectedClient: {
        ...... values
      }
    }

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:25:13)

  console.log
    3

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:27:15)

  console.log
    profile null

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:21:11)

  console.log
    2

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:23:13)

  console.log
    { selectedClient: undefined }

      at SelectedClientWrapper (src/components/SelectedClientWrapper/SelectedClientWrapper.tsx:25:13)

  console.log
    <body>
      <div>
        <div>
          clients
        </div>
      </div>
    </body>

为什么不更新上下文?我错过了什么?

0 个答案:

没有答案