【问题标题】:Testing useDispach with jest用玩笑测试 useDispach
【发布时间】:2020-07-31 10:50:07
【问题描述】:

我正在尝试使用 jest 测试 useDispach

这是我的组件ItemInput.js:

const ItemInput = ({ value, title, action, type, placeholder }) => {
    const dispatch = useDispatch();
    return (
        <div>
            <span data-cy="title">{title}</span>

            <Input
                type={type}
                value={value}
                onChange={e =>
                    dispatch({
                        type: action,
                        payload: { value: e.target.value }
                    })
                }
                placeholder={placeholder}
                data-cy={`item-input-${title}`}
            />
        </div>
    );
};

这是我的测试:

import React from 'react';
import { mount } from 'enzyme';
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import ItemInput from '../ItemInput';

const mockStore = configureMockStore([thunk]);
const store = mockStore({});
const setup = () => {
    const props = {
        action: 'SET_NAME',
        value: 'test',
        title: 'title',
        type: 'text',
        placeholder: ''
    };

    const component = mount(
        <Provider store={store}>
            <ItemInput {...props} />
        </Provider>
    );

    const input = component.find(`[data-cy="item-input-${props.title}"]`).first();

    return {
        component,
        input,
        props
    };
};

describe('ItemInput', () => {
    it('should render correctly', () => {
        const { component } = setup();
        expect(component.find('ItemInput').exists()).toEqual(true);
    });

    it('should call dispach when typing', () => {
        const { input, props } = setup();
        store.dispatch = jest.fn();
        input.simulate('change', { target: { value: 'Jack' } });

        expect(store.dispatch).toHaveBeenCalledWith({
            type: props.action,
            payload: { value: 'Jack' }
        });
    });
});

预期的行为是 dispatch{type: props.action,payload: { value: 'Jack'}} 调用。

但出现错误:

expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: {"payload": {"value": "Jack"}, "type": "SET_NAME"}

Number of calls: 0

  60 |         input.simulate('change', { target: { value: 'Jack' } });
  61 | 
> 62 |         expect(store.dispatch).toHaveBeenCalledWith({
     |                                ^
  63 |             type: props.action,
  64 |             payload: { value: 'Jack' }
  65 |         });

我认为input.simulate('change', { target: { value: 'Jack' } });有一些问题,它没有触发调度功能。

知道怎么解决吗?

【问题讨论】:

    标签: react-redux jestjs react-hooks


    【解决方案1】:

    回答您的问题,问题是您在安装组件后正在模拟 store dispatch 方法。

    这会导致组件以 store 的原始值挂载,并且您的模拟没有考虑在内。

    要解决这个问题,您只需更改测试的顺序,以便在使用商店之前进行 dispatch 模拟:

    it('should call dispatch when typing', () => {
        store.dispatch = jest.fn();
        const { input, props } = setup();
        input.simulate('change', { target: { value: 'Jack' } });
    
        expect(store.dispatch).toHaveBeenCalledWith({
            type: props.action,
            payload: { value: 'Jack' }
        });
    });
    

    作为替代解决方案,由于您已经在使用redux-mock-store 库,您可以通过调用store.getActions 来触发所有操作。因此,测试动作是否被触发的更简洁的方法是:

    it('should call dispatch when typing', function() {
        const { input, props } = setup();
        input.simulate('change', { target: { value: 'Jack' } });
    
        const actions = store.getActions();
        expect(actions).toEqual([{
            type: props.action,
            payload: { value: 'Jack' }
        }]);
    });
    

    【讨论】:

    • 嗨,@mgarcia,感谢您的回答,我已经实施了您的解决方案,但我仍然遇到同样的错误。
    • 也许你有不同的想法?我把这个codesandbox 放在一起,你可以比较一下。
    • 感谢代码沙箱,我已经复制并粘贴了代码并得到了同样的错误。这么奇怪的事情:/。我可能缺少一些配置?你知道是否有其他方法可以测试 useDispatch 吗?
    • 嗨@GN,我已经提供了一个应该可行的替代解决方案。希望对您有所帮助!
    猜你喜欢
    • 2021-02-10
    • 1970-01-01
    • 2018-01-29
    • 2019-02-22
    • 2020-11-14
    • 1970-01-01
    • 2017-11-29
    • 2020-07-04
    • 2020-06-30
    相关资源
    最近更新 更多