【问题标题】:How to test with Jest whether action created by action creator (and not passed as prop) fires?如何用 Jest 测试由动作创建者创建的动作(而不是作为道具传递)是否触发?
【发布时间】:2022-01-04 14:22:58
【问题描述】:

我尝试测试给定的操作是否真的在组件中被触发。如果带有操作的回调作为道具传递可能很容易,但我不清楚在我的情况下如何做到这一点。这是组件:

export const Modal = (props: appendProps): JSX.Element => {
    const { items, activeScope } = props;
    const primary = items[0] === activeScope;
    const { closeInput, appendItem } = useDispatchAction();
{...}
    <Button
      variant="contained"
      size="large"
      className="modal-content__button"
      color="secondary"
      onClick={() => {
           closeInput();
      }}
      >
       Zamknij
   </Button>

useDispatchAction 如下:

import { useDispatch } from 'react-redux';
import { bindActionCreators } from 'redux';
import { actionCreators } from '../redux';

const useDispatchAction = () => {
    const dispatch = useDispatch();
    return bindActionCreators(actionCreators, dispatch);
};

export default useDispatchAction;

并在下面测试自己

describe('Test button actions', () => {
    const closeInput = jest.fn();
    jest.mock('../../src/hooks/useDispatchAction', () => ({closeInput}));

    beforeEach(() => {
        render(<Modal />);
    });
    afterEach(() => cleanup());
    test('component fires closeInput', () => {
        const closeButton = screen.getByRole('button', { name: 'Zamknij' });
        expect(closeButton).toBeInTheDocument();
        userEvent.click(closeButton);
        expect(closeInput).toBeCalled();
    });
});

但这一直告诉我该函数已被调用 0 次而不是至少 1 次

【问题讨论】:

    标签: reactjs jestjs


    【解决方案1】:

    当你jest.mock 时,你会得到一个默认返回undefined 的函数。所以,如果useDispatchAction返回undefined,你就不能去const { closeInput, appendItem } = useDispatchAction();,因为你不能从undefined解构。

    但是,您可以supply a second argumentjest.mock

    const closeInput = jest.fn()
    jest.mock('../../src/hooks/useDispatchAction', () => ({ closeInput }))
    

    现在您已经模拟了 useDispatchAction 以返回看起来更像您的原始函数的东西,除了该操作返回的东西您可以断言被调用。

    你可以这样测试:

    expect(closeInput).toHaveBeenCalled()

    我认为这应该可以,但我还没有测试过这个特定的代码。

    【讨论】:

    • 肯定更好,现在没有错误,而且它没有注意到任何调用。
    • 我不确定,但我想知道您是否需要将其设为异步。你可以尝试导入waitFor,使你传递给test的函数异步,然后像这样包装你的期望:await waitFor(() =&gt; expect(closeInput).toBeCalled())
    【解决方案2】:

    最终起作用的是:

    const actions = {
        closeInput: jest.fn(),
        appendItem: jest.fn(),
    };
    
    jest.mock('../../src/hooks/useDispatchAction', () => () => actions);
    
    describe('Given Modal component', () => {
        describe('when "Zamknij" button is clicked', () => {
            it('should call closeInput function', async () => {
                actions.closeInput.mockClear();
    
                const { findByText } = render(<Modal />);
                const closeButton = await findByText('Zamknij');
    
                fireEvent.click(closeButton);
    
                expect(actions.closeInput).toHaveBeenCalled();
            });
        });
    });
    
    

    【讨论】:

      猜你喜欢
      • 2015-10-16
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      • 2021-05-30
      • 1970-01-01
      • 2019-01-08
      • 2017-04-14
      • 2017-12-12
      相关资源
      最近更新 更多