我正在尝试测试是否使用正确的参数调用了函数,但是由于我使用的是来自react-redux的useDispatch,因此出现以下错误:操作必须是普通对象。使用自定义中间件执行异步操作。
我已经按照文档中的说明将测试组件包装在renderWithRedux中。
测试设置:
const renderWithRedux = (
ui,
{ initialState, store = createStore(reducer, initialState) } = {}
) => {
return {
...render(<Provider store={store}>{ui}</Provider>),
store,
};
};
const templateId = faker.random.number();
const setup = () => {
const props = {
history: {
push: jest.fn(),
},
};
viewTemplateUrl.mockImplementationOnce(() => jest.fn(() => () => {}));
templatePostThunk.mockImplementationOnce(
jest.fn(() => () => Promise.resolve(templateId))
);
const {
container,
getByText,
getByLabelText,
rerender,
debug,
} = renderWithRedux(<NewTemplateForm {...props} />);
return {
debug,
templateId,
props,
container,
rerender,
getByText,
getByLabelText,
templateNameTextField: getByLabelText('Template Name'),
templateNameInput: getByLabelText('Template Name Input'),
saveTemplateButton: getByText('Save Template'),
cancelButton: getByText('Cancel'),
};
};
Failing test:
test('save template calls handleSubmit, push, and viewTemplateUrl', async () => {
const { templateNameInput, saveTemplateButton, props } = setup();
fireEvent.change(templateNameInput, { target: { value: 'Good Day' } });
fireEvent.click(saveTemplateButton);
await expect(templatePostThunk).toHaveBeenCalledWith({
name: 'Good Day',
});
expect(props.history.push).toHaveBeenCalled();
expect(viewTemplateUrl).toHaveBeenCalledWith({ templateId });
});
应该过去了。
答案 0 :(得分:0)
您正试图派遣一个笨拙的动作创建者:
await expect(templatePostThunk).toHaveBeenCalledWith({
name: 'Good Day',
});
但是您要设置的商店没有笨拙的中间件:
store = createStore(reducer, initialState)
您需要将thunk中间件添加到createStore()
调用中,以使其正常工作。
答案 1 :(得分:0)
答案是模拟useDispatch并将父组件包装在renderWithRedux中。
import { render, fireEvent } from '@testing-library/react';
import '@testing-library/react/cleanup-after-each';
import { useDispatch } from 'react-redux';
import faker from 'faker';
import { NewTemplateForm } from './NewTemplateForm';
import { templatePostThunk } from '../../../redux/actions/templatePost';
import { viewTemplateUrl } from '../../../utils/urls';
jest.mock('../../../redux/actions/templatePost');
jest.mock('../../../utils/urls');
jest.mock('react-redux');
describe('<NewTemplateForm/> controller component', () => {
useDispatch.mockImplementation(() => cb => cb());
const setup = () => {
const props = {
history: {
push: jest.fn(),
},
};
const templateId = faker.random.number();
viewTemplateUrl.mockImplementationOnce(() => () => {});
templatePostThunk.mockImplementationOnce(() => async () => ({
data: { id: templateId },
}));
const { container, getByText, getByLabelText, rerender, debug } = render(
<NewTemplateForm {...props} />
);