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

1l5u6lss  于 2023-03-02  发布在  iOS
关注(0)|答案(1)|浏览(133)

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

获取令牌.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的响应。在 response 中,数据对象应该包括 errors 数组。

获取令牌.测试.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 -示例.ts**

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

测试未通过。

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
  }

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

mpbci0fu

mpbci0fu1#

是的,我解决了2个不同的选项.
由于@jonrsharpe,axios示例应该与. test. ts和. ts文件相同。

    • api根目录. ts**
import axios from "axios";
export const apiRoot = axios.create({
    headers: {
        "Access-Control-Allow-Origin": "*",
        "Content-Type": "application/json",
    }
})
    • 获取令牌. 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**:使用axios进行测试
    • 获取令牌.测试. 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);
    })
})

不要干扰Axios
安装软件包
npm安装msw--保存设备

    • 获取令牌.测试. 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);
    })
})

相关问题