在 React 开玩笑 API 测试中未调用模拟函数且未解析或返回模拟值
Mock function not called and not resolving or returning mocked value in React jest API testing
我正在使用 jest 来测试 axios API 调用。模拟 API 不是解析或返回值,也不会调用模拟函数。这是我的 API 调用和测试代码。
这是具有postData功能的基础服务文件
import axios from 'axios';
const API_ENDPOINT = process.env.REACT_APP_API_ENDPOINT;
function setHeader(contentType:string, token:string|undefined) {
return {
'Accept': 'application/json',
'Content-Type': contentType,
'Authorization': `Bearer ${token}`,
};
}
async function postData(path:string, contentType:string, token:string|undefined,
payload:FormData | Record<string, any> | string) {
return axios({
method: 'post',
url: `${API_ENDPOINT}${path}`,
headers: setHeader(contentType, token),
data: payload,
});
}
export {postData}
这是我试过的测试文件代码。
import '@testing-library/jest-dom';
import axios from 'axios';
import confirmProfile from '../../apis/onboard/confirmProfile';
jest.mock('axios');
const mockAxios=axios as jest.Mocked<typeof axios>;
const VALID_TOKEN='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzZXNzaW9uIjoicmRjZDhpbXduOXl0YjZ5eTRrN3I4NnJsb3RjcnZ0cHkiLCJuYmYiOjE2NTI2NzYyNTguMzcwNTUyOCwiaXNzIjoiZ296ZWFsIn0.IR1hNOZPY4rcrykJgzrGkgfJM9vJNuveG-KS8BYaxnI';
it("Confirm profile original file with valid params",async ()=>{
const res={confirmProfileData: { isSuccess: false },
apiError: undefined,
}
mockAxios.post.mockResolvedValueOnce(res);
const response = await confirmProfile(VALID_TOKEN);
console.log('profile',response);
expect(mockAxios.post).toHaveBeenCalledTimes(1);
expect(response).toEqual(res);
})
测试结果
FAIL src/__tests__/apis/Testing.test.ts
✕ Confirm profile original file with valid params (10 ms)
● Confirm profile original file with valid params
expect(jest.fn()).toHaveBeenCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 0
27 | const response = await confirmProfile(VALID_TOKEN);
28 | console.log('profile',response);
> 29 | expect(mockAxios.post).toHaveBeenCalledTimes(1);
| ^
30 | expect(response).toEqual(res);
31 | })
32 |
at Object.<anonymous> (src/__tests__/apis/Testing.test.ts:29:28)
console.log
profile { confirmProfileData: { isSuccess: true }, apiError: undefined }
at Object.<anonymous> (src/__tests__/apis/Testing.test.ts:32:1)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.857 s, estimated 3 s
模拟函数未被调用,模拟值未解析或记录
问题是由于您的代码没有直接调用 axios 模块实例上的 post 函数,而是通过 json 参数隐式调用,而您的测试模拟正在寻找直接 axios.post 电话。有两种方法可以解决此问题。
1。将隐式 post 调用更改为显式调用:
发件人:
axios({
method: 'post',
url: `${API_ENDPOINT}${path}`,
headers: setHeader(contentType, token),
data: payload,
})
收件人:
axios.post(`${API_ENDPOINT}${path}`, payload, { headers: setHeader(contentType, token) })
2. 在测试套件设置中模拟 axios post 调用:
发件人:
jest.mock("axios")
到
jest.mock("axios", () => {
const expectedResponse = JSON.stringify({
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxZDY2OTF",
"issued_token_type": "token-type:access_token",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "consumer_profile:read:"
});
return () => new Promise((resolve) => resolve(expectedResponse));
})
这将通过部分模拟来模拟隐式 post 调用,但是您将无法直接访问 post
方法,因此您将无法专门监听它的调用.
我正在使用 jest 来测试 axios API 调用。模拟 API 不是解析或返回值,也不会调用模拟函数。这是我的 API 调用和测试代码。
这是具有postData功能的基础服务文件
import axios from 'axios';
const API_ENDPOINT = process.env.REACT_APP_API_ENDPOINT;
function setHeader(contentType:string, token:string|undefined) {
return {
'Accept': 'application/json',
'Content-Type': contentType,
'Authorization': `Bearer ${token}`,
};
}
async function postData(path:string, contentType:string, token:string|undefined,
payload:FormData | Record<string, any> | string) {
return axios({
method: 'post',
url: `${API_ENDPOINT}${path}`,
headers: setHeader(contentType, token),
data: payload,
});
}
export {postData}
这是我试过的测试文件代码。
import '@testing-library/jest-dom';
import axios from 'axios';
import confirmProfile from '../../apis/onboard/confirmProfile';
jest.mock('axios');
const mockAxios=axios as jest.Mocked<typeof axios>;
const VALID_TOKEN='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzZXNzaW9uIjoicmRjZDhpbXduOXl0YjZ5eTRrN3I4NnJsb3RjcnZ0cHkiLCJuYmYiOjE2NTI2NzYyNTguMzcwNTUyOCwiaXNzIjoiZ296ZWFsIn0.IR1hNOZPY4rcrykJgzrGkgfJM9vJNuveG-KS8BYaxnI';
it("Confirm profile original file with valid params",async ()=>{
const res={confirmProfileData: { isSuccess: false },
apiError: undefined,
}
mockAxios.post.mockResolvedValueOnce(res);
const response = await confirmProfile(VALID_TOKEN);
console.log('profile',response);
expect(mockAxios.post).toHaveBeenCalledTimes(1);
expect(response).toEqual(res);
})
测试结果
FAIL src/__tests__/apis/Testing.test.ts
✕ Confirm profile original file with valid params (10 ms)
● Confirm profile original file with valid params
expect(jest.fn()).toHaveBeenCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 0
27 | const response = await confirmProfile(VALID_TOKEN);
28 | console.log('profile',response);
> 29 | expect(mockAxios.post).toHaveBeenCalledTimes(1);
| ^
30 | expect(response).toEqual(res);
31 | })
32 |
at Object.<anonymous> (src/__tests__/apis/Testing.test.ts:29:28)
console.log
profile { confirmProfileData: { isSuccess: true }, apiError: undefined }
at Object.<anonymous> (src/__tests__/apis/Testing.test.ts:32:1)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.857 s, estimated 3 s
模拟函数未被调用,模拟值未解析或记录
问题是由于您的代码没有直接调用 axios 模块实例上的 post 函数,而是通过 json 参数隐式调用,而您的测试模拟正在寻找直接 axios.post 电话。有两种方法可以解决此问题。
1。将隐式 post 调用更改为显式调用:
发件人:
axios({
method: 'post',
url: `${API_ENDPOINT}${path}`,
headers: setHeader(contentType, token),
data: payload,
})
收件人:
axios.post(`${API_ENDPOINT}${path}`, payload, { headers: setHeader(contentType, token) })
2. 在测试套件设置中模拟 axios post 调用:
发件人:
jest.mock("axios")
到
jest.mock("axios", () => {
const expectedResponse = JSON.stringify({
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxZDY2OTF",
"issued_token_type": "token-type:access_token",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "consumer_profile:read:"
});
return () => new Promise((resolve) => resolve(expectedResponse));
})
这将通过部分模拟来模拟隐式 post 调用,但是您将无法直接访问 post
方法,因此您将无法专门监听它的调用.