最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to test header, axios.defaults.headers, with Jest? - Stack Overflow

programmeradmin5浏览0评论

In my application, I have a middleware to check for a token in a req in order to access private routes:

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.' });
  }
};

In order to send a req with the correct token in my program's Redux actions, I call the following function, setAuthToken(), to set the auth token:

import axios from 'axios';

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

export default setAuthToken;

My Redux action using axios and the setAuthToken() function:

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) {
    // ...
  }
};

How can I write a test to test setAuthToken()? The following is my attempt:

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.headersmon['x-auth-token']).toBe('test token');
    });
});

The following is the error I get:

TypeError: Cannot read property 'headers' of undefined

Looking up this error, it sounds like it is because there is no req in my test. If that is the case, how can I re-write my test to send a req? If not, what am I doing wrong?

In my application, I have a middleware to check for a token in a req in order to access private routes:

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.' });
  }
};

In order to send a req with the correct token in my program's Redux actions, I call the following function, setAuthToken(), to set the auth token:

import axios from 'axios';

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

export default setAuthToken;

My Redux action using axios and the setAuthToken() function:

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) {
    // ...
  }
};

How can I write a test to test setAuthToken()? The following is my attempt:

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.mon['x-auth-token']).toBe('test token');
    });
});

The following is the error I get:

TypeError: Cannot read property 'headers' of undefined

Looking up this error, it sounds like it is because there is no req in my test. If that is the case, how can I re-write my test to send a req? If not, what am I doing wrong?

Share Improve this question asked Oct 27, 2020 at 23:01 BrendanBrendan 8622 gold badges10 silver badges24 bronze badges 1
  • Use console.log(axios) in your test file to check if it is being mocked? – Lin Du Commented Oct 28, 2020 at 3:31
Add a ment  | 

1 Answer 1

Reset to default 5

Here is my case, there is a __mocks__ directory in my project. There is a mocked axios. More info about __mocks__ directory, see Manual mock

__mocks__/axios.ts:

const axiosMocked = {
  get: jest.fn()
};
export default axiosMocked;

When I run the test you provide, got the same error as yours. Because mocked axios object has no defaults property. That's why you got the error.

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

jest.unmock('axios');

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.mon['x-auth-token']).toBe('test token');
  });
});

So I use jest.unmock(moduleName) to use the real axios module instead of the mocked one.

After that, it works fine. Unit test result:

 PASS  src/stackoverflow/64564148/setAuthToken.test.ts (10.913s)
  setAuthToken utility function.
    ✓ Sets the axios header, x-auth-token, with a token. (5ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        13.828s

Another possible reason is you enable automock. Check both mand and jest.config.js file.

发布评论

评论列表(0)

  1. 暂无评论