代码之家  ›  专栏  ›  技术社区  ›  filipyoo

检测Redux酶:状态改变后组件不会重新呈现

  •  0
  • filipyoo  · 技术社区  · 6 年前

    我有一个连接的组件(到Redux商店)叫做drauravatar,我为了测试目的(酶+Jest)导出了连接和非连接版本。

    基本上,我想测试我的DrawerAvatar在我的Redux状态下呈现用户avatar isAuthenticated true ,并在 已验证 false .

    drawravatar.js公司

    export class DrawerAvatar extends React.Component {
      render () {
        const avatarSrc = this.props.isAuthenticated ?
          'http://user-avatar.png'
        ) : (
          'http://logo.png'
        );
    
        return (
          <StyledAvatarContainer>
            <StyledAvatar src={avatarSrc} />
          </StyledAvatarContainer>
        );
      }
    }
    
    const mapStateToProps = state => ({
      isAuthenticated: state.authReducer.isAuthenticated
    });
    
    export default compose(
      connect(mapStateToProps, null)
    )(DrawerAvatar);
    

    在我的测试中,我使用了未连接的DrawerAvatar,并将其连接到 通过 Provider 例如:(缩写状态: isAuthenticated: false )

    :

    import React from 'react';
    import { shallow } from 'enzyme';
    import { Provider } from 'react-redux';
    
    import store from '../../store';
    import connectedDrawerAvatar, { DrawerAvatar } from './DrawerAvatar';
    
    describe('Header > DrawerAvatar: component', () => {
      it('should render logo for the DrawerAvatar if not authenticated, and the user avatar if authenticated', () => {
        const wrapper = shallow(<Provider store={store}><DrawerAvatar /></Provider>);
        console.log(wrapper.dive().debug());
        // Output: 
        // <StyledAvatarContainer>
        //  <StyledAvatar src="https://logo.png" />
        // </StyledAvatarContainer>    
        const StyledAvatarSrc = wrapper.dive().find('StyledAvatar').prop('src');
        expect(StyledAvatarSrc).toBe('https://logo.png'); // assertion passed
    
        store.dispatch({ type: 'LOGIN_WITH_EMAIL_REQUESTED_TEST' });
        // the state has been correctly updated, now isAuthenticated: true
    
        console.log(wrapper.dive().debug());
        // Output: same as above, whereas it should be: 
        // <StyledAvatarContainer>
        //  <StyledAvatar src="https://user-avatar.png" />
        // </StyledAvatarContainer>    
        expect(StyledAvatarSrc).toBe('https://user-avatar.png'); // assertion failed
      });
    });
    

    这是我的authReducer:

    const initialState = {
      isAuthenticated: false
    };
    
    export default function authReducer (state = initialState, action) {
      switch (action.type) {
        case 'LOGIN_WITH_EMAIL_REQUESTED_TEST':
          return {
            ...state,
            isAuthenticated: true,
          };
        default:
          return state;
      }
    }
    

    所以基本上,我有一个真正的动作 LOGIN_WITH_EMAIL_REQUESTED 这将称为Axios的一系列Redux传奇,但出于测试的目的,我刚刚添加到真正的authReducer中 LOGIN_WITH_EMAIL_REQUESTED_TEST 已验证 真的 为了避免Axios调用等…不确定这是不是一个好的方法来做事情

    我试图强制组件使用 wrapper.update() ...

    我刚开始写我的第一个反应测试所以…谢谢!

    1 回复  |  直到 6 年前
        1
  •  1
  •   Mitch Lillie    6 年前

    基本上,我想测试我的DrawerAvatar在我的Redux状态isAuthenticated为true时呈现用户avatar,在isAuthenticated为false时呈现徽标图片。

    我建议不要连接整个已连接的组件,而是尝试使用Redux。您可以通过以下方法达到预期的效果:

    describe('Header > DrawerAvatar: component', () => {
      it('should render logo for the DrawerAvatar if not authenticated, and the user avatar if authenticated', () => {
        let wrapper = shallow(<DrawerAvatar isAuthenticated={false} />);
        let StyledAvatarSrc = wrapper.find('StyledAvatar').prop('src');
        expect(StyledAvatarSrc).toBe('https://logo.png');
        wrapper = shallow(<DrawerAvatar isAuthenticated={true} />);
        StyledAvatarSrc = wrapper.find('StyledAvatar').prop('src');
        expect(StyledAvatarSrc).toBe('https://user-avatar.png');
      });
    });
    

    然后,可以为涉及的每个部分编写单独的测试,例如 mapStateToProps 函数,它实际上只是一个简单的函数,根据输入返回一个对象。另一个简单的测试 authReducer