在Jest和Typescript中使用自定义错误mock axios



我想用自定义错误对象来嘲弄axios的post请求。

getToken.ts

const GetToken = async (params:ITokenParams):Promise<ITokenResult | IError>=>{
try{
const api = axios.create({
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
},
});
const {data} = await api.post<ITokenResult>("https://someURL", { ...params });
return data;
}
catch(e){
let err:IError={
error:true,
module:path.basename(__filename),
method:GetToken.name
};
if(e instanceof AxiosError && e.response?.data?.errors){
let errorsArray:IApiError[]=e.response?.data?.errors;
err.message=errorsArray.length>0?errorsArray[0].detail : e.message;
}
else if (e instanceof Error){
err.message=e.message
}
return err;
}
}
export default GetToken;

自定义错误对象是mockResponse。我想返回状态为401的响应。在响应中,数据对象应该包含错误数组。

getToken.test.ts

import {axiosInstance} from '../../utils/axios-instance';
import GetToken from '@App/api/oauth/getToken';
jest.mock('../../utils/axios-instance.ts');
describe('Token from OAuth', () => {
test('Return error for expired code', async () => {
const mockResponse = {
data:{}, 
status: 401,
statusText:"Unauthorized",
headers: {}, 
config: {} , 
response:{ 
data: { errors: [{ detail: 'a' }] } 
}
};
const response = {
error: true,
module: 'getToken.ts',
method: 'GetToken',
message: 'a'
};
const mockedAxiosInstance = axiosInstance as jest.MockedFunction<typeof axiosInstance>;
(mockedAxiosInstance.post as jest.Mock).mockRejectedValueOnce(mockResponse);
const result= await GetToken({
client_id:process.env.APPLICATION_ID,
client_secret:process.env.APPLICATION_SECRET,
code:"some-codes",
grant_type:"authorization_code"
});
expect(result).toEqual(response);
})
})

axios-instance.ts

import axios from "axios";
export const axiosInstance = axios.create({
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
}
})

The test is fail.

Object {
"error": true,
-   "message": "a",
+   "message": "Request failed with status code 400",
"method": "GetToken",
"module": "getToken.ts",
}

当我检查catch语句中的代码时,该块运行

else if (e instanceof Error){
err.message=e.message
}

我如何返回我的自定义错误对象?

是的,我用两个不同的选项来解决。

感谢@jonrsharpe, axios实例应该是相同的。. Ts和. Ts文件。

apiRoot.ts

import axios from "axios";
export const apiRoot = axios.create({
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
}
})

getToken.ts

...
import {apiRoot} from '@App/utils/apiRoot';
const GetToken = async (params:ITokenParams):Promise<ITokenResult | IError>=>{
try{
// This line change with apiRoot. We don't use axios.create.
const {data} = await apiRoot.post<ITokenResult>("someURL", { ...params });
return data;
}
catch(e){
...
}
}
export default GetToken;

选项1: Test with axios

getToken.test.ts

import {apiRoot} from '@App/utils/apiRoot';
import GetToken from '@App/square-api/oauth/getToken';
import {AxiosError} from 'axios';
//mock the instance from apiRoot
jest.mock('@App/utils/apiRoot.ts');
describe('Token from OAuth', () => {
test('Return error for expired code', async () => {
// Expected response from GetToken method
const response = {
error: true,
module: 'getToken.ts',
method: 'GetToken',
message: 'a'
};
const mockedAxiosInstance = apiRoot as jest.MockedFunction<typeof apiRoot>;

(mockedAxiosInstance.post as jest.Mock).mockRejectedValueOnce(new AxiosError("Unauthorized","401",{},{},
{
data: { errors: [{ detail: 'a' }] },
status:401,
statusText:'Unauthorized',
headers:{},
config:{}
}));
const result= await GetToken({
client_id:process.env.APPLICATION_ID,
client_secret:process.env.APPLICATION_SECRET,
code:"some-code",
grant_type:"authorization_code"
});

expect(result).toEqual(response);
})
})

选项2: Mock Service Worker

别惹Axios

安装包

npm install msw——save-dev

getToken.test.ts

import { rest } from 'msw'
import { setupServer } from 'msw/node'
import GetToken from '@App/square-api/oauth/getToken';
const mockResponse =  { errors: [{ detail: 'a' }] } ;
const response = {
error: true,
module: 'getToken.ts',
method: 'GetToken',
message: 'a'
};
const server = setupServer(
// Url should be same with post request in getToken.ts 
rest.post("someURL", (req, res, ctx) => {
return res(
ctx.set('Content-Type', 'application/json'),
ctx.status(401),
ctx.json({...mockResponse})
)
})
)
beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
describe('Token from OAuth', () => {
test('Return error for expired code', async () => {
const result= await GetToken({
client_id:process.env.APPLICATION_ID,
client_secret:process.env.APPLICATION_SECRET,
code:"some-code",
grant_type:"authorization_code"
});

expect(result).toEqual(response);
})
})

最新更新