IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> jest+testing-library/react 单元测试 react+antd 的实践(二) -> 正文阅读

[JavaScript知识库]jest+testing-library/react 单元测试 react+antd 的实践(二)

阅读本编文章请先看 jest+testing-library/react 单元测试 react+antd 的实践(一) 获取安装以及基本语法知识,下面讲从真实业务场景 antd+react 来写单元测试的例子

axios 测试

前端业务一般发请求用的是axios,会对axios进行包装,用请求拦截器 和 response拦截器 对请求和返回进行封装,场景是请求添加header: Authorization: Bearer token 返回根据返回结果进行判断采取不同的措施,例如登陆过期就跳登出,接口报错就弹窗错误消息,代码如下:

const createAxiosInstance = (): AxiosInstance => {
  const instance = axios.create({
    validateStatus: () => true, // 不管返回的 http 状态码是多少,都不抛出错误,在响应拦截器中进行处理
  });

  // 请求拦截器
  instance.interceptors.request.use((config) => {
    config.headers = {
      ...config.headers,
      Authorization: `Bearer ${auth.getToken()}`,
    };
    return config;
  });

  // 响应拦截器
  instance.interceptors.response.use((res: AxiosResponse<Res>) => {
    const data = res.data;

    // 登陆失效,并跳转到登录页面
    if (res.status === 401) {
      message.error('登录状态已失效,请重新登录');
      setTimeout(() => {
        auth.logout();
      }, 1000);

      throw new Error('token invalid');
    }

    // 接口报错 弹出错误信息
    if (data.errorCode !== ErrCode.Success) {
      // errCode 不为 success 的情况,说明后端返回了一个业务错误
      message.error(data.errorInfo || '未知错误,请联系管理员');
      // 将业务错误往外抛,打断正常代码执行,或者被 try catch 捕获
      throw data;
    }

    // 此时 errCode 为 success,不管状态码或其他数据怎么样,都默认为请求成功
    return { ...res, data };
  });

  return instance;
};

export class Api {
  readonly axios = createAxiosInstance();
}

相对应的测试代码

jest.mock('../service/auth');
class MockApi extends Api {
  client = this.axios;
}

let timerSpy: jest.SpyInstance;
const api = new MockApi();
beforeEach(() => {
  jest.useFakeTimers();
  timerSpy = jest.spyOn(global, 'setTimeout');
});
afterEach(() => {
  timerSpy.mockRestore();
});
describe('test api/api.ts', () => {
  it('接口请求拦截 headers:{Authorization: Bearer token}', () => {
    const interceptorsRequest: any = api.client.interceptors.request;

    expect(interceptorsRequest.handlers[0].fulfilled({})).toStrictEqual({
      headers: { Authorization: 'Bearer token' },
    });
  });
 it('当status=401时,弹出提示:登录状态已失效,请重新登录,1秒后登出', () => {
   const interceptorsResponse: any = api.client.interceptors.response;
    const data = { errorCode: 500 };
    try {
      interceptorsResponseResolved = interceptorsResponse.handlers[0].fulfilled({
        data,
        request: { responseURL: '' },
        status: 401,
      });
    } catch (e) {
      expect(e).toStrictEqual(new Error('token invalid'));
    }

  expect(message.error).toBeCalledWith('登录状态已失效,请重新登录');
  expect(setTimeout).toHaveBeenCalledTimes(1);
  expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 1000);
  expect(interceptorsResponseResolved).toBeUndefined();
  jest.runAllTimers();
  expect(auth.logout).toBeCalled();
  });

 it('当请求成功,返回结果当errorCode不为0时,弹出errorInfo的错误消息', () => {
    let interceptorsResponseResolved: any;
    const data = { errorCode: 500, errorInfo: 'errorInfo' };
    try {
      interceptorsResponseResolved = interceptorsResponse.handlers[0].fulfilled({
        data,
        request: { responseURL: '' },
        status: 200,
      });
    } catch (e) {
      expect(e).toStrictEqual(data);
    }

    expect(message.error).toBeCalledWith(data.errorInfo);
    expect(interceptorsResponseResolved).toBeUndefined();
  });
})

说明: jest.mock 模拟auth的方法 详见上一遍
antd 的 message 方法mock 见下面一章节

antd mock

antd message 方法模拟

对于没有dom的function单独测试时 不能直接判断有没有出现改message元素,可以判断message.error message.warn 方法有没有被调用 可以mock antd

export const messageErrorMock = jest.fn();

jest.mock('antd', () => {
  const antd = jest.requireActual('antd');

  return {
    ...antd,
    message: {
      ...antd.message,
      error: jest.fn,
    },
  };
});

这个代码可以放在测试文件开头 也可以放在根目录的setupTest.ts文件里 启动时会自动调用
在测试时 向上面的例子就可以直接判断 expect(messageErrorMock).toBeCalledWith(data.errorInfo); 是否调用了这个方法 以及传入的参数。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:13:49  更:2022-07-17 16:15:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/11 12:32:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码