Javascript 如何使用Jest测试React中的条件渲染?新组件呈现时包装器是否更新?

Javascript 如何使用Jest测试React中的条件渲染?新组件呈现时包装器是否更新?,javascript,reactjs,testing,react-router,jestjs,Javascript,Reactjs,Testing,React Router,Jestjs,我已经编写了以下代码: 验证用户-输入用户名和密码 请求被发送到身份验证服务器,令牌被接收并存储在本地存储器中 成功存储令牌后,将调度一个操作以将存储状态从isLoggedin:false更改为isLoggedin:true 将状态更改为true时,它会将我重定向到新组件 使用jest,我试图只测试相同功能的行为 我正在使用Moxios模拟Axios请求 如何使用Jest进行测试,以了解已呈现新组件 下面是我的代码: // eslint-disable-next-line import Reac

我已经编写了以下代码:

  • 验证用户-输入用户名和密码
  • 请求被发送到身份验证服务器,令牌被接收并存储在本地存储器中
  • 成功存储令牌后,将调度一个操作以将存储状态从
    isLoggedin:false
    更改为
    isLoggedin:true
  • 将状态更改为true时,它会将我重定向到新组件
  • 使用jest,我试图只测试相同功能的行为
  • 我正在使用Moxios模拟Axios请求
  • 如何使用Jest进行测试,以了解已呈现新组件

    下面是我的代码:

    // eslint-disable-next-line
    import React, { Component } from 'react';
    import './Form.css';
    import { Redirect } from 'react-router-dom';
    import { store } from '../../store';
    import { LOGIN } from '../../constants/actionTypes';
    import { connect } from 'react-redux';
    import Spiiner from '../Spiiner';
    import { showLoader } from '../../actions';
    import { hideLoader } from '../../actions';
    import axios from 'axios';
    
    interface IProps {
      login: any;
      dispatch: any;
    }
    
    interface IState {
      username: string;
      password: string;
    }
    
    export class Login extends Component<IProps, IState> {
      constructor(props: any) {
        super(props);
    
        this.state = {
          username: '',
          password: '',
        };
      }
    
      componentDidMount() {
        this.storeCollector();
      }
    
      storeCollector() {
        let localStore = localStorage.getItem('login');
        if (localStore) {
          store.dispatch({ type: LOGIN, payload: { isLoggedIn: true } });
        }
      }
    
      handleUsernameChange = (event: any) => {
        this.setState({
          username: event.target.value,
        });
      };
    
      handlePassword = (event: any) => {
        this.setState({
          password: event.target.value,
        });
      };
    
       login() {
       // this.props.dispatch(showLoader());
        axios
          .post('https://reqres.in/api/login', {
            email: this.state.username,
            password: this.state.password,
          })
          .then(
            (response) => {
              console.log(response.data);
          //    this.props.dispatch(hideLoader());
              if (response.status===200) {
                localStorage.setItem(
                  'login',
                  JSON.stringify({ token: response.data })
                );
                
                store.dispatch({ type: LOGIN, payload: { isLoggedIn: true } });
              } else {
                store.dispatch({ type: LOGIN, payload: { isLoggedIn: false } });
              }
            },
            (error) => {
              console.log(error);
      //       this.props.dispatch(hideLoader());
            }
          );
       }
    
      render() {
        let loginPage = (
          <div className="form">
            <form className="form-signin">
              <div className="text-center mb-4">
                <h1>Login</h1>
                <img
                  className="mb-4"
                  src="/docs/4.5/assets/brand/bootstrap-solid.svg"
                  alt=""
                  width="72"
                  height="72"
                ></img>
              </div>
    
              <div className="form-label-group">
                <input
                  type="email"
                  id="inputEmail"
                  className="form-control"
                  placeholder="Email address"
                  value={this.state.username}
                  onChange={this.handleUsernameChange}
                />{' '}
                <br></br>
              </div>
    
              <div className="form-label-group">
                <input
                  type="password"
                  id="inputPassword"
                  className="form-control"
                  placeholder="Password"
                  value={this.state.password}
                  onChange={this.handlePassword}
                />
              </div>
    
              <button
                className="btn btn-lg btn-dark"
                type="button"
                onClick={() => {
                  this.login();
                }}
              >
                Sign in
              </button>
            </form>
            <a href="">
              <img
                id="img"
                src=""
                alt=""
              />
            </a>
            <Spiiner />
          </div>
        );
    
        return (
          <div>
            {!this.props.login ? <div>{loginPage}</div> : <Redirect to="/search" />}
          </div>
        );
      }
    }
    
    interface RootState {
      login: any;
    }
    
    const mapStateToProps = (state: RootState) => {
      console.log(state.login.isLoggedIn);
    
      return {
        login: state.login.isLoggedIn,
      };
    };
    
    export default connect(mapStateToProps)(Login);
    
    //eslint禁用下一行
    从“React”导入React,{Component};
    导入“/Form.css”;
    从'react router dom'导入{Redirect};
    从“../../store”导入{store};
    从“../../constants/actionTypes”导入{LOGIN};
    从'react redux'导入{connect};
    从“../Spiiner”导入Spiiner;
    从“../../actions”导入{showLoader};
    从“../../actions”导入{hideLoader};
    从“axios”导入axios;
    接口IProps{
    登录:任意;
    派遣:任何;
    }
    界面状态{
    用户名:字符串;
    密码:字符串;
    }
    导出类登录扩展组件{
    构造器(道具:任何){
    超级(道具);
    此.state={
    用户名:“”,
    密码:“”,
    };
    }
    componentDidMount(){
    this.storeCollector();
    }
    storeCollector(){
    让localStore=localStorage.getItem('login');
    if(本地存储){
    dispatch({type:LOGIN,payload:{isLoggedIn:true}});
    }
    }
    handleUsernameChange=(事件:任意)=>{
    这是我的国家({
    用户名:event.target.value,
    });
    };
    handlePassword=(事件:任意)=>{
    这是我的国家({
    密码:event.target.value,
    });
    };
    登录(){
    //this.props.dispatch(showLoader());
    axios
    .post('https://reqres.in/api/login', {
    电子邮件:this.state.username,
    密码:this.state.password,
    })
    .那么(
    (回应)=>{
    console.log(response.data);
    //this.props.dispatch(hideLoader());
    如果(响应状态===200){
    localStorage.setItem(
    “登录”,
    stringify({token:response.data})
    );
    dispatch({type:LOGIN,payload:{isLoggedIn:true}});
    }否则{
    dispatch({type:LOGIN,payload:{isLoggedIn:false}});
    }
    },
    (错误)=>{
    console.log(错误);
    //this.props.dispatch(hideLoader());
    }
    );
    }
    render(){
    让登录页面=(
    登录
    {' '}
    

    { this.login(); }} > 登录 ); 返回( {!this.props.login?{loginPage}:} ); } } 接口根状态{ 登录:任意; } 常量mapStateToProps=(状态:RootState)=>{ console.log(state.login.isLoggedIn); 返回{ 登录名:state.login.isLoggedIn, }; }; 导出默认连接(MapStateTops)(登录);
    我的测试文件是:

    import { mount } from 'enzyme';
    import { configure } from 'enzyme';
    import Adapter from 'enzyme-adapter-react-16';
    import { Login } from './Components/Form/Login';
    import React from 'react';
    import renderer from 'react-test-renderer';
    import { store } from './store/index';
    import { Provider } from 'react-redux';
    import { BrowserRouter as Router } from 'react-router-dom';
    import { makeMockStore } from '../MockUtil/utils';
    import moxios from 'moxios';
    import { MemoryRouter } from 'react-router-dom'
    
    
    configure({ adapter: new Adapter() });
    
    const setUp = (props = {}) => {
      const component = mount(
        <Provider store={store}>
          <Router>
            <Login />
          </Router>
        </Provider>
      );
      return component;
    };
    
    it('render correctly text component', () => {
      const LoginComponent = renderer
        .create(
          <Provider store={store}>
            <Login />
          </Provider>
        )
        .toJSON();
      expect(LoginComponent).toMatchSnapshot();
    });
    
    let wrapper: any;
    
    describe('Login Page test', () => {
      let component;
      beforeEach(() => {
        wrapper = setUp();
      });
    
      // it('Shows spinner on Button click', () => {
      //   console.log(wrapper.html());
      //   wrapper.find('button').simulate('click');
      //   expect(wrapper.contains(<div className="spinner-grow" />)).toEqual(true);
      //   console.log(wrapper.html());
      // });
    
      it('check for existence of form', () => {
        const form = wrapper.find('form');
        expect(form.length).toBe(1);
      });
    });
    
    describe('Moxios', () => {
      beforeEach(() => {
        moxios.install();
        wrapper = setUp();
      });
      afterEach(() => {
        moxios.uninstall();
      });
    
    
    
      it('Calls the login class method on click', () => {
        const spyPreventDefault = jest.spyOn(Login.prototype, 'login');
        wrapper.find('button').simulate('click');
        expect(spyPreventDefault).toHaveBeenCalledTimes(1);
      });
    
      global.window = { location: { pathname: null } };
    
      it('specify response for a specific request', function (done) {
        console.log(wrapper.html());
        wrapper.find('button').simulate('click');
        moxios.wait(function () {
          let request = moxios.requests.mostRecent();
          request
            .respondWith({
              status: 200,
              response: {
                token: '8972fjh45kbwbrhg4hj5g',
              },
            })
            .then(function () {
              done();
            });
        });
      });
    });
    
    从“酶”导入{mount};
    从“酶”导入{configure};
    从'enzyme-Adapter-react-16'导入适配器;
    从“./Components/Form/Login”导入{Login};
    从“React”导入React;
    从“反应测试渲染器”导入渲染器;
    从“./store/index”导入{store};
    从'react redux'导入{Provider};
    从“react Router dom”导入{BrowserRouter as Router};
    从“../MockUtil/utils”导入{makeMockStore};
    从“moxios”导入moxios;
    从'react router dom'导入{MemoryRouter}
    配置({adapter:newadapter()});
    const setUp=(props={})=>{
    常量组件=挂载(
    );
    返回组件;
    };
    它('正确呈现文本组件',()=>{
    const LoginComponent=渲染器
    .创造(
    )
    .toJSON();
    expect(LoginComponent.toMatchSnapshot();
    });
    让我们看看:任何;
    描述('登录页面测试',()=>{
    let组件;
    在每个之前(()=>{
    包装器=设置();
    });
    //它('单击按钮时显示微调器',()=>{
    //log(wrapper.html());
    //wrapper.find('button').simulate('click');
    //expect(wrapper.contains()).toEqual(true);
    //log(wrapper.html());
    // });
    它('检查表单的存在',()=>{
    const form=wrapper.find('form');
    expect(形式长度)toBe(1);
    });
    });
    描述('Moxios',()=>{
    在每个之前(()=>{
    moxios.install();
    包装器=设置();
    });
    之后(()=>{
    moxios.uninstall();
    });
    它('单击时调用登录类方法',()=>{
    const spyPreventDefault=jest.spyOn(Login.prototype,'Login');
    wrapper.find('button').simulate('click');
    expect(spyPreventDefault).toHaveBeenCalledTimes(1);
    });
    global.window={location:{pathname:null}};
    它('指定特定请求的响应',函数(完成){
    log(wrapper.html());
    wrapper.find('button').simulate('click');
    moxios.wait(函数(){
    let request=moxios.requests.mostRecent();
    要求
    .回应({
    现状:200,
    答复:{
    令牌:“8972fjh45kbwbrhg4hj5g”,
    },
    })
    .然后(函数(){
    完成();
    });
    });
    });
    });
    
    我想测试新组件的重定向和渲染

    请引导我


    注:这是我第一次处理测试。

    只需将
    login
    道具传递给您的
    login
    组件:

    const component = mount(
        <Provider store={store}>
          <Router>
            <Login login={true} />
          </Router>
        </Provider>
      );
    
    或者,您可以将
    重定向
    更改为
    历史。推送expect(window.location.href).toContain('search');
    
    componentWillReceiveProps(nextProps) {
      if(nextProps.login)
        this.props.history.push('/search');
      }
    }
    
    import {useHistory} from 'react-router-dom';
    ...
    const history = useHistory();
    
    componentWillReceiveProps(nextProps) {
      if(nextProps.login)
        history.push('/search');
      }
    }