如何使用 Jest 测试标头 axios.defaults.headers?

Bre*_*dan 2 javascript http-headers reactjs jestjs axios

在我的应用程序中,我有一个中间件来检查 a 中的令牌req,以便访问私有路由:

const config = require('../utils/config');
const jwt = require('jsonwebtoken');

module.exports = function (req, res, next) {
  let token = req.header('x-auth-token');

  if (!token) {
    return res.status(401).json({ msg: 'No token. Authorization DENIED.' });
  }

  try {
    let decoded = jwt.verify(token, config.JWTSECRET);
    req.user = decoded.user;
    next();
  } catch (err) {
    return res.status(401).json({ msg: 'Token is invalid.' });
  }
};
Run Code Online (Sandbox Code Playgroud)

为了req在程序的 Redux 操作中发送正确的令牌,我调用以下函数 setAuthToken() 来设置身份验证令牌:

import axios from 'axios';

const setAuthToken = token => {
  if (token) {
    axios.defaults.headers.common['x-auth-token'] = token;
  } else {
    delete axios.defaults.headers.common['x-auth-token'];
  }
};

export default setAuthToken;
Run Code Online (Sandbox Code Playgroud)

我使用 axios 和 setAuthToken() 函数的 Redux 操作:

export const addPost = (formData) => async (dispatch) => {
  try {
    //set the token as the header to gain access to the protected route POST /api/posts
    if (localStorage.token) {
      setAuthToken(localStorage.token);
    }

    const config = {
      headers: {
        'Content-Type': 'application/json',
      },
    };

    const res = await axios.post('/api/posts', formData, config);

    // ...

  } catch (err) {
    // ...
  }
};
Run Code Online (Sandbox Code Playgroud)

如何编写测试来测试 setAuthToken()?以下是我的尝试:

import axios from 'axios';
import setAuthToken from '../../src/utils/setAuthToken';

describe('setAuthToken utility function.', () => {
    test('Sets the axios header, x-auth-token, with a token.', () => {
        let token = 'test token';

        setAuthToken(token);
        expect(axios.defaults.headers.common['x-auth-token']).toBe('test token');
    });
});
Run Code Online (Sandbox Code Playgroud)

以下是我得到的错误:

TypeError: Cannot read property 'headers' of undefined
Run Code Online (Sandbox Code Playgroud)

req查了一下这个错误,听起来好像是因为我的测试中没有。如果是这种情况,我该如何重写我的测试来发送req?如果不是,我做错了什么?

sli*_*wp2 5

__mocks__这是我的情况,我的项目中有一个目录。有一个嘲笑axios__mocks__有关目录的更多信息,请参阅手动模拟

\n

__mocks__/axios.ts:

\n
const axiosMocked = {\n  get: jest.fn()\n};\nexport default axiosMocked;\n
Run Code Online (Sandbox Code Playgroud)\n

当我运行您提供的测试时,出现与您相同的错误。因为模拟axios对象没有defaults属性。这就是您收到错误的原因。

\n
import axios from \'axios\';\nimport setAuthToken from \'./setAuthToken\';\n\njest.unmock(\'axios\');\n\ndescribe(\'setAuthToken utility function.\', () => {\n  test(\'Sets the axios header, x-auth-token, with a token.\', () => {\n    let token = \'test token\';\n    setAuthToken(token);\n    expect(axios.defaults.headers.common[\'x-auth-token\']).toBe(\'test token\');\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

所以我使用jest.unmock(moduleName)来使用真实的axios模块而不是模拟的模块。

\n

之后,它工作正常。单元测试结果:

\n
 PASS  src/stackoverflow/64564148/setAuthToken.test.ts (10.913s)\n  setAuthToken utility function.\n    \xe2\x9c\x93 Sets the axios header, x-auth-token, with a token. (5ms)\n\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        13.828s\n
Run Code Online (Sandbox Code Playgroud)\n

另一个可能的原因是您启用了automock。检查命令和jest.config.js文件。

\n