我刚开始测试并尝试测试异步数据获取。我做错了什么动作。或者我如何测试它? axios.mockResolvedValueOnce(result) 表示 属性 'mockResolvedValueOnce' 不存在于类型 'AxiosStatic'
api.ts
export const createAccount = createAsyncThunk(
'account/createAccount',
async (Info: User) => {
try {
return await axios.post(APIUrl + 'users.json', Info);
} catch (err) {
const { status, errorMessage } = err?.response?.data;
const error: ErrorResponse = {
status: status,
message: errorMessage,
};
return error;
}
},
);
api.test.ts
import axios from 'axios';
import { createAccount } from '../api';
jest.mock('axios');
describe('user account', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('should return data if status code equals 200', async () => {
const result = {
status: 200,
data: {},
};
axios.post.mockResolvedValueOnce(result); <-- Property 'mockResolvedValueOnce' does not exist on type 'AxiosStatic'
const actual = await createAccount({
id: '1',
firstName: 'first name',
lastName: 'last name',
email: 'email',
phone: 'phone',
});
expect(actual).toEqual({});
expect(axios).toBeCalledWith({
method: 'post',
url: 'http://localhost:3000/',
headers: { 'content-type': 'application/json' },
data: { id: '1', firstName: 'first name', lastName: 'last name', email: 'email', phone: 'phone' },
});
});
it('should throw error if status code equals 400', async () => {
const result = { status: 400, message: jest.fn().mockReturnValue('network') };
});
});
答案 0 :(得分:0)
createAsyncThunk
返回一个标准的 Redux thunk 动作创建者。不是 axios.post()
的返回值。您可以在此处找到 redux thunk 动作创建者的类型 AsyncThunkAction。因此,您可以创建一个模拟的 dispatch
函数、getState
函数并将它们传递给它。
我们模拟了 axios.post
方法,所以我们应该断言这个方法是用参数而不是 axios
函数调用的。
例如
api.ts
:
import axios from 'axios';
import { createAsyncThunk } from '@reduxjs/toolkit';
const APIUrl = 'http://localhost:3000/';
export interface User {}
export interface ErrorResponse {}
export const createAccount = createAsyncThunk('account/createAccount', async (Info: User) => {
try {
return await axios.post(APIUrl + 'users.json', Info);
} catch (err) {
const { status, errorMessage } = err?.response?.data;
const error: ErrorResponse = {
status: status,
message: errorMessage,
};
return error;
}
});
api.test.ts
:
import axios from 'axios';
import { createAccount, ErrorResponse, User } from './api';
import { AsyncThunkAction } from '@reduxjs/toolkit';
jest.mock('axios');
describe('user account', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('should return data if status code equals 200', async () => {
const dispatch = jest.fn();
const result = {
status: 200,
data: {},
};
(axios.post as jest.MockedFunction<typeof axios.post>).mockResolvedValueOnce(result);
const createAccountAsyncThunkAction: AsyncThunkAction<ErrorResponse, User, {}> = createAccount({
id: '1',
firstName: 'first name',
lastName: 'last name',
email: 'email',
phone: 'phone',
});
const actual = await createAccountAsyncThunkAction(dispatch, () => {}, undefined);
expect(actual.meta.arg).toEqual({
id: '1',
firstName: 'first name',
lastName: 'last name',
email: 'email',
phone: 'phone',
});
expect(actual.payload).toEqual({ status: 200, data: {} });
expect(axios.post).toBeCalledWith('http://localhost:3000/users.json', {
id: '1',
firstName: 'first name',
lastName: 'last name',
email: 'email',
phone: 'phone',
});
});
});
单元测试结果:
PASS examples/65845191/api.test.ts
user account
✓ should return data if status code equals 200 (3 ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 70 | 0 | 100 | 66.67 |
api.ts | 70 | 0 | 100 | 66.67 | 13-19
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.423 s, estimated 4 s
包版本:
"axios": "^0.21.1",
"jest": "^26.6.3",
"@reduxjs/toolkit": "^1.5.0",