首页 > 解决方案 > 在 React 组件笑话测试中模拟 Axios 实例和拦截器

问题描述

我正在测试一个调用 API 来用数据填充表的组件。尽管使用了 axios,但 axios 被包装在一种方便的方法中,以便在通过拦截器执行请求之前填充标头。我已经尝试过 axios-mock-adapter,但它不起作用。我仍然是测试 React 的新手,我对如何模拟从 api/axios 返回的数据一无所知。如何模拟 api 调用来模拟数据以使我的测试通过?

这是我的简单测试:

test('<EmailTable/> ', async () => {
  const { debug, getByText } = render(<CommunicationEmail />);
  await waitFor(() => expect(getByText('Test Email Subject')).toBeTruthy());
}

这是 axios 包装器(api.js):

const instance = axios.create({
  baseURL: `${apiUrl}/v1`,
  timeout: 12000,
  withCredentials: true,
  headers: headers,
});

//intercept requests to validate hashed auth token
instance.interceptors.request.use((request) => {
  const token = request.headers['X-Our-Access-Token'];
  if (
    localStorage.getItem('user_token') == null ||
    SHA256(token).toString(enc.Hex) == localStorage.getItem('user_token')
  ) {
    return request;
  } else {
    console.log({ what: 'Auth key invalid' });
    return Promise.reject('Invalid token!');
  }
});

//intercept responses to handle 401 errors
instance.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    // handle 401 authentication errors and redirect to SSO
    if (error.response != null && error.response.status != null && error.response.status === 401) {
      console.error({ what: 'Authorization error', e: error });
    }
    return Promise.reject(error);
  }
);

export default instance;

这是我要测试的组件的简化:

import api from './api.js';

const EmailTable = () => {
   const [emails, setEmails] = useState();

   useEffect(() => {
      if(!emails) {
         getEmails();
      }
   }, [emails]);

   const getEmails = async () => { 
      await api({
        method: 'GET',
        url: `/communications/emails`,
      }).then((response) => {
        if (response.success) {
           setEmails(response.emails);
        }
      }
    }

   if(!emails) { return <div> Loading... </div> }; 
   return <div>{emails}</div>;
}

更新解决方案:

为了模拟作为我的 API 的 axios 包装器,我必须模拟 api 模块并返回一个已解决的承诺,如下所示:

jest.mock('../api', () => {
  return function (request) {
    // If we want to mock out responses to multiple API requests, we could do if (request.url = "/blah/blah") { return new Promise.... }
    return new Promise((resolve) => {
      resolve({
        data: { success: true, emails: [] },
      });
    });
  };
});

标签: reactjsjestjsaxiosreact-testing-libraryaxios-mock-adapter

解决方案


推荐阅读