gpt4 book ai didi

javascript - redux-thunk结构和测试副作用

转载 作者:行者123 更新时间:2023-11-28 03:55:45 25 4
gpt4 key购买 nike

我正在使用 redux-thunk 并且不确定副作用(showAlertError 函数)的结构是否正确。虽然我的 Jest 测试设置乍一看似乎没问题,但我收到一个错误:

jest.fn() value must be a mock function or spy. Received: undefined`

showAlertError 函数是否位于正确的位置,或者应该位于操作创建者中或其他位置?另外,如果这是它的正确位置,那么我如何测试它是否被调用。

export const submitTeammateInvitation = (data) => {
const config = {
// config code
};

return async (dispatch) => {
dispatch(submitTeammateInvitationRequest(data));

try {
const response = await fetch(inviteTeammateEndpoint, config);
const jsonResponse = await response.json();
if (!response.ok) {
showErrorAlert(jsonResponse);
dispatch(submitTeammateInvitationError(jsonResponse));

throw new Error(response.statusText);
}

dispatch(submitTeammateInvitationSuccess(jsonResponse));
} catch (error) {
if (process.env.NODE_ENV === 'development') {
console.log('Request failed', error);
}
}
};
};

测试

import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';

import { showAlertError } from '../../../../_helpers/alerts';
jest.mock('../../../../_helpers/alerts');

const middlewares = [thunk];
const createMockStore = configureMockStore(middlewares);

describe('submitTeammateInvitation', () => {
it('dispatches the correct actions on a failed fetch request', () => {
fetch.mockResponse(
JSON.stringify(error),
{ status: 500, statusText: 'Internal Server Error' }
);

const store = createMockStore({});
const expectedActions = [
submitTeammateInvitationRequestObject,
submitTeammateInvitationErrorObject
];
const showAlertError = jest.fn();

return store.dispatch(submitTeammateInvitation(inviteTeammateEndpoint))
.then(() => {
expect(showAlertError).toBeCalled(); // this doesn't work
expect(store.getActions()).toEqual(expectedActions); // this works
});
});
});

最佳答案

您可以手动模拟 showErrorAlert 函数。解决办法如下:

actionCreators.ts:

import fetch from 'node-fetch';
import { showErrorAlert } from './showErrorAlert';

const SUBMIT_TEAMATE_INVITATION_REQUEST = 'SUBMIT_TEAMATE_INVITATION_REQUEST';
const SUBMIT_TEAMATE_INVITATION_SUCCESS = 'SUBMIT_TEAMATE_INVITATION_SUCCESS';
const SUBMIT_TEAMATE_INVITATION_ERROR = 'SUBMIT_TEAMATE_INVITATION_ERROR';

export const submitTeammateInvitationRequest = data => ({ type: SUBMIT_TEAMATE_INVITATION_REQUEST, payload: { data } });
export const submitTeammateInvitationSuccess = data => ({ type: SUBMIT_TEAMATE_INVITATION_SUCCESS, payload: { data } });
export const submitTeammateInvitationError = data => ({ type: SUBMIT_TEAMATE_INVITATION_ERROR, payload: { data } });

export const submitTeammateInvitation = data => {
const config = {
// config code
};

const inviteTeammateEndpoint = 'https://github.com/mrdulin';

return async dispatch => {
dispatch(submitTeammateInvitationRequest(data));

try {
const response = await fetch(inviteTeammateEndpoint, config);
const jsonResponse = await response.json();
if (!response.ok) {
showErrorAlert(jsonResponse);
dispatch(submitTeammateInvitationError(jsonResponse));

throw new Error(response.statusText);
}

dispatch(submitTeammateInvitationSuccess(jsonResponse));
} catch (error) {
if (process.env.NODE_ENV === 'development') {
console.log('Request failed', error);
}
}
};
};

showErrorAlert.ts:

export function showErrorAlert(jsonResponse) {
console.log(jsonResponse);
}

actionCreators.spec.ts:

import {
submitTeammateInvitation,
submitTeammateInvitationRequest,
submitTeammateInvitationSuccess,
submitTeammateInvitationError
} from './actionCreators';
import createMockStore from 'redux-mock-store';
import thunk, { ThunkDispatch } from 'redux-thunk';
import fetch from 'node-fetch';
import { AnyAction } from 'redux';
import { showErrorAlert } from './showErrorAlert';

const { Response } = jest.requireActual('node-fetch');

jest.mock('node-fetch');
jest.mock('./showErrorAlert.ts', () => {
return {
showErrorAlert: jest.fn()
};
});

const middlewares = [thunk];
const mockStore = createMockStore<any, ThunkDispatch<any, any, AnyAction>>(middlewares);

describe('submitTeammateInvitation', () => {
it('dispatches the correct actions on a failed fetch request', () => {
const mockedResponse = { data: 'mocked response' };
const mockedJSONResponse = JSON.stringify(mockedResponse);
const mockedData = { data: 'mocked data' };
(fetch as jest.MockedFunction<typeof fetch>).mockResolvedValueOnce(
new Response(mockedJSONResponse, { status: 500, statusText: 'Internal Server Error' })
);

const intialState = {};
const store = mockStore(intialState);
const expectedActions = [
submitTeammateInvitationRequest(mockedData),
submitTeammateInvitationError(mockedResponse)
];
return store.dispatch(submitTeammateInvitation(mockedData)).then(() => {
expect(store.getActions()).toEqual(expectedActions);
expect(showErrorAlert).toBeCalledWith(mockedResponse);
});
});
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/47560126/actionCreators.spec.ts
submitTeammateInvitation
✓ dispatches the correct actions on a failed fetch request (11ms)

-------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-------------------|----------|----------|----------|----------|-------------------|
All files | 89.29 | 50 | 83.33 | 90.91 | |
actionCreators.ts | 89.29 | 50 | 83.33 | 90.91 | 32,35 |
-------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.864s

这是已完成的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/47560126

关于javascript - redux-thunk结构和测试副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47560126/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com