微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

两个后坐力反应测试基于渲染值发生冲突

如何解决两个后坐力反应测试基于渲染值发生冲突

我有一个原子来存储一个带有 authTokenusername 字符串的对象。如果 authToken 存在,我想展示受保护的内容。如果没有,我想将用户重定向登录页面

测试:

  1. 不填充“authToken”,我们希望呈现的结果中包含登录内容
  2. 填充“authToken”,我希望呈现的结果中包含受保护的内容

当按顺序 2,1 执行时,他们成功了。当按顺序 1,2 执行时,它们会失败。

我想知道我是否遗漏了什么或者这是一个已知问题。任何帮助将不胜感激。

原子

import { atom } from 'recoil';

type AuthDetail = {
  authToken?: string;
  userName?: string;
};

const authStateAtom = atom<AuthDetail>({
  key: 'auth-state',default: {},});

export { authStateAtom };
export type { AuthDetail };

私人路线

import React,{ FC } from 'react';
import { authStateAtom } from './atom';
import { Redirect,Route,RouteProps } from 'react-router-dom';
import { useRecoilValue } from 'recoil';

const PrivateRoute: FC<RouteProps> = ({ children,...rest }) => {
  const authState = useRecoilValue(authStateAtom);

  return (
    <Route
      {...rest}
      render={({ location }) =>
        authState.authToken ? (
          children
        ) : (
          <Redirect
            to={{
              pathname: '/login',state: { from: location },}}
          />
        )}
    />
  );
}

export { PrivateRoute };

测试

import { act,render,RenderResult } from '@testing-library/react';
import React from 'react';
import { HashRouter,Switch } from 'react-router-dom';
import { MutableSnapshot,RecoilRoot } from 'recoil';
import { authStateAtom } from './atom';
import { PrivateRoute } from './PrivateRoute';

describe('PrivateRoute:',() => {
  const protectedComponent = 'protected-component';
  const loginComponent = 'login-component';

  it('redirects to login if not authenticated',async () => {
    let result: RenderResult;
    await act(async () => {
      result = render(
        <RecoilRoot>
          <Switch>
            <Route exact={true} path="/login">
              <div data-testid={loginComponent}>LOGIN COMPONENT</div>
            </Route>
            <PrivateRoute path="/">
              <div data-testid={protectedComponent}>PROTECTED COMPONENT</div>
            </PrivateRoute>
          </Switch>
        </RecoilRoot>,{ wrapper: HashRouter },)
    });

    // @ts-ignore
    expect(result.getByTestId(loginComponent)).toBeInTheDocument();
    // @ts-ignore
    expect(result.queryByTestId(protectedComponent)).not.toBeInTheDocument();
  });


  it('renders the component if authenticated',async () => {
    const initialRecoilState = (snap: MutableSnapshot) => {
      snap.set(authStateAtom,{ authToken: '1234' });
    };
    let result: RenderResult;
    await act(async () => {
      result = render(
        <RecoilRoot initializeState={initialRecoilState}>
          <Switch>
            <Route exact={true} path="/login">
              <div data-testid={loginComponent}>LOGIN COMPONENT</div>
            </Route>
            <PrivateRoute path="/">
              <div data-testid={protectedComponent}>PROTECTED COMPONENT</div>
            </PrivateRoute>
          </Switch>
        </RecoilRoot>,);
    });

    // @ts-ignore
    expect(await result.findByTestId(protectedComponent)).toBeInTheDocument();
    // @ts-ignore
    expect(result.queryByTestId(loginComponent)).not.toBeInTheDocument();
  });


});

https://codesandbox.io/s/vigilant-shamir-27s35?file=/src/PrivateRoute.test.tsx

解决方法

当您使用 <Router> 进行测试时,环境中的 window.history 可能会受到污染。如果您只运行一项测试,另一项将通过。但是当您一起运行它们时,您的第一个测试会将 URL 设置为 "/login"。您将在第二次测试中开始使用该网址。

根据react-router's testing guide,你应该用<MemoryRouter>包裹你的组件以保护全球环境。

这是两个测试都通过的代码和框链接:https://codesandbox.io/s/frosty-rhodes-xxuwk?file=/src/PrivateRoute.test.tsx

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。