我有一个称为DrawerAvatar的连接组件(到Redux商店),我将其导出以用于测试目的(酶+笑话),包括连接版本和非连接版本。
基本上,我想测试当我的Redux状态isAuthenticated
为true
时我的DrawerAvatar呈现用户头像,而当isAuthenticated
为false
时它呈现徽标图片
DrawerAvatar.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
将其连接到我的 real Redux存储,如下所示:(初始状态:{{1 }})
DrawerAvatar.test.js :
isAuthenticated: false
这是我的authReducer:
authReducer.js
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
});
});
因此,基本上,我有一个类型为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;
}
}
的真实动作,它将使用Axios调用一堆Redux-saga,但出于测试目的,我只是在我的真实authReducer中添加了一个LOGIN_WITH_EMAIL_REQUESTED
例会将状态LOGIN_WITH_EMAIL_REQUESTED_TEST
设置为isAuthenticated
以避免Axios调用等...虽然不确定这是做事的好方法。.lol
我曾试图用true
来强制组件更新...
我也看过redux-mock-store,但似乎您不能修改状态,只能处理操作而不是状态。
我刚刚开始编写我的第一个React测试,所以...谢谢!
答案 0 :(得分:1)
基本上,我想测试当我的Redux状态为isAuthenticated为true时,我的DrawerAvatar呈现用户头像,而当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
等的另一个简单测试