我有一个简单的连接组件,该组件在加载时会通过调用异步操作来构建用户详细信息,然后从状态中显示这些详细信息。
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import { loadUserDetails } from '../actions/user';
class ShowUserDetailsLite extends React.Component {
componentDidMount() {
this.props.loadUserDetails();
}
render() {
const { userDetails } = this.props;
const handleClickEdit = () => {
history.push(editProfilePath());
};
return (
<div>
<div className="email">
{userDetails.email_address}
</div>
<div className="name">
{userDetails.first_name} {userDetails.last_name}
</div>
</div>
);
}
}
ShowUserDetailsLite.propTypes = {
loadUserDetails: PropTypes.func.isRequired,
userDetails: PropTypes.shape({}).isRequired,
};
const mapDispatchToProps = {
loadUserDetails,
};
function mapStateToProps(state) {
const userDetails = state.user.details;
return { userDetails };
}
export default connect(mapStateToProps, mapDispatchToProps)(ShowUserDetailsLite);
首先,我想测试我的组件从状态显示了正确的信息,因此我进行了以下测试。
import configureStore from 'redux-mock-store'
import { shallow } from 'enzyme';
import { expect } from 'chai';
import React from 'react'
import Provider from 'react-redux';
import ShowUserDetailsLite from '../../components/ShowUserDetailsLite'
describe('ShowUserDetailsLite component', () => {
it('displays the current user', () => {
const mockStore = configureStore();
let store = mockStore({
user: {
details: {
email_address: 'test@test.com',
first_name: 'First',
last_name: 'Last',
}
},
});
let wrapper = shallow(<ShowUserDetailsLite store={store} loadUserDetails={jest.fn()}/>).dive()
expect(wrapper.find('.email').text()).to.eql('test@test.com')
})
})
当我用componentDidMount
函数注释掉运行此测试时,它运行良好,可以读取状态并显示正确的信息,但是当我运行包含componentDidMount
函数的测试时,尝试进行测试调用该函数,然后出现以下错误:
FAIL app/tests/components/ShowUserDetailsLite.test.js
ShowUserDetailsLite component
✕ displays the current user (32ms)
● ShowUserDetailsLite component › displays the current user
ReferenceError: regeneratorRuntime is not defined
16 |
17 | export function loadUserDetails() {
> 18 | return async dispatch => {
| ^
19 | try {
20 | const res = await axios.get(`/${window.realm}/api/userDetails`);
21 | dispatch({ type: SET_USER_DETAILS, data: res.data });
在此阶段,我不关心测试loadUserDetails函数,因此我只想对它进行存根。我了解,要做到这一点,您只需要将函数作为属性传递即可,而我尝试通过传递一个笑话函数来做到这一点:
let wrapper = shallow(<ShowUserDetailsLite store={store} loadUserDetails={jest.fn()}/>).dive()
但是仍然出现错误。如何正确地对在componentdidmount中调用的异步操作存根进行连接的组件测试?
答案 0 :(得分:0)
我可能来晚了,但最终我也因同样的问题而苦苦挣扎,在挖掘了两天之后,我发现:
由于使用Connect包装了组件,因此需要将残存的props函数传递给子组件
您可以在没有HOC连接的情况下导出组件
export ShowUserDetailsLite
然后导入
import {ShowUserDetailsLite} from ...
现在您的组件变浅了,没有连接,您可以直接传递道具,例如用户和模拟的loadUserDetails
要更完整地回答原始问题:
当您mount
或shallow
使用组件时,您将触发componentDidMount。
浅处
对于shallow
渲染,您可以使用选项{disableLifecycleMethods:true}
wrapper = shallow(
<Stats {...props} />, {disableLifecycleMethods:true}
)
带支架
如果您想使用mount
进行渲染,则需要对componentDidMount进行如下操作:
jest.spyOn(YOUCOMPONENT.prototype, 'componentDidMount').mockImplementation();
然后安装组件
wrapper = mount(
<Stats {...props} />
)
现在,如果您想存根componentDidMount中调用的方法,则可以访问这些方法:
const spy = jest.spyOn(wrapper.instance(), 'myMethod').mockImplementation(() => {//do stuff})