如何用 Jest 覆盖 mapDispatchToProps 中的行?

Posted

技术标签:

【中文标题】如何用 Jest 覆盖 mapDispatchToProps 中的行?【英文标题】:How to cover lines in mapDispatchToProps with Jest? 【发布时间】:2019-11-25 15:51:11 【问题描述】:

我的问题是我们如何开玩笑地涵盖这些行?

export const mapDispatchToProps = dispatch => 
    return 
        submitClaimsForm: form => 
            dispatch(submitClaimsForm(form));
        
    ;
;

在我的组件中,redux 连接区域如下所示:

export function mapStateToProps(state) 
    return 
        formNonMember: state.form,
        submissionSuccess: state.claimSubmission.submissionSuccess
    ;


export const mapDispatchToProps = dispatch => 
    return 
        submitClaimsForm: form => 
            dispatch(submitClaimsForm(form));
        
    ;
;

let AdditionalDetailsFormConnect = reduxForm(
    form: 'AdditionalDetails',
    destroyOnUnmount: false
)(AdditionalDetailsForm);

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(AdditionalDetailsFormConnect);

这就是调度操作的使用方式:

onSubmit() 
    this.props.submitClaimsForm(this.props.formattedForm);

接下来是实际操作的样子:

import postClaimsForm from '../shared/services/api';

export const Actions = 
    SET_SUBMISSION_STATUS: 'SET_SUBMISSION_STATUS'
;

export const submitClaimsForm = form => dispatch => 
    return postClaimsForm(form)
        .then(res => 
            // console.log('promise returned:', res);
            return dispatch(
                type: Actions.SET_SUBMISSION_STATUS,
                submissionSuccess: true
            );
        )
        .catch(error => 
            // console.log('error returned:', error);
            return dispatch(
                type: Actions.SET_SUBMISSION_STATUS,
                submissionSuccess: false
            );
        );
;

到目前为止我所做的尝试:

it('mapDispatchToProps works as expected', () => 
    const actionProps = mapDispatchToProps(
        submitClaimsForm: jest.fn()
    );
    actionProps.submitClaimsForm();
    expect(submitClaimsForm).toHaveBeenCalled();
);

但是这个错误告诉我dispatch 是未定义的。

我也有这个测试,它通过了,它告诉我 submitClaimsForm 已被调用,但它只覆盖了 onSubmit 的行:

it('onSubmit is called on submit', function() 
    const spyOnSubmit = jest.spyOn(wrapper.instance(), 'onSubmit');
    const mockHandleSubmit = jest.fn(wrapper.instance().onSubmit);
    const submitClaimsForm = jest.fn(wrapper.instance().submitClaimsForm);

    wrapper.setProps(
        handleSubmit: mockHandleSubmit,
        submitClaimsForm
    );

    wrapper.find('MyForm').simulate('submit');

    expect(mockHandleSubmit).toHaveBeenCalled();
    expect(spyOnSubmit).toHaveBeenCalled();
    expect(submitClaimsForm).toHaveBeenCalled();  // <--
);

【问题讨论】:

嗯,您尝试编写的测试的真正目的是什么?测试mapDispatchToProps 有点感觉就像你在测试react-redux。第二个测试看起来更适合 IMO,尽管它更像是一个集成测试。 @James 哦,是的,我们已经完全覆盖了 Actions 文件......该函数 submitClaimsForm 已经过测试,但开玩笑的只是线路覆盖 :( 【参考方案1】:

您的mapDispatchToProps works as expected 测试失败的原因是mapDispatchToProps 期望传入dispatch 函数,而不是映射本身(这就是mapDispatchToProps 返回)。

这应该可行:

jest.mock('./actions');
import * as actions from './actions';

it('mapDispatchToProps calls the appropriate action', async () => 
  // mock the 'dispatch' object
  const dispatch = jest.fn();
  const actionProps = mapDispatchToProps(dispatch);
  const formData =  ... ;
  actionProps.submitClaimsForm(formData);
  // verify the appropriate action was called
  expect(actions.submitClaimsForm).toHaveBeenCalled(formData);
);

【讨论】:

以上是关于如何用 Jest 覆盖 mapDispatchToProps 中的行?的主要内容,如果未能解决你的问题,请参考以下文章

如何用 jest 测试 combineReducers

如何用 jest 测试 redux saga?

如何用 Jest 模拟/替换对象的 getter 函数?

如何用 Jest 正确实现这样的测试套件架构?

如何用 Jest 测试一系列数字?

如何用 jest 测试 nuxt?