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

javascript - How to test auth headers with Jest? - Stack Overflow

programmeradmin0浏览0评论

I am attempting to test the auth header when doing an api call:

import axios from 'axios';
import ApiClient from './apiClient';
import ApiService from './apiService';

jest.mock('./apiClient', () => {
  return {
    headers: { authorization: 'Bearer test token' },
    get: jest.fn()
  };
});

describe('apiService methods', () => {
  beforeAll(() => {
    ApiClient.get.mockImplementation((url: string) => {
      return Promise.resolve({ data: mockData });
    });
  });

  it('getArticles method call', () => {
    ApiService.getArticles(jest.fn(), 1, 3, 'latest', 'news', 'selectedNews');

    expect(axios.defaults.headersmon.Authorization).toBe(
      'Bearer test token'
    ); // THIS GIVES UNDEFINED SO THE TEST FAILS

    expect(ApiClient.get).toBeCalledWith(
      '/content?type=article&page=1&limit=3&sort=latest&facet=news&article_category=selectedNews'
    );
  });
});

This is what I have on ApiClient to request the header:

import axios from 'axios';
import envs from '../../config/index.json';

const client = axios.create({
  baseURL: envs.data.data.centralApi.baseUrl + apiVersion
});

client.defaults.headersmon.Authorization = `Bearer ${localStorage.getItem(
  `adal.access.token.key${envs.data.data.adal.clientId}`
)}`;

So I need to test that the Authorization header is properly send when the api call is performed.

What should I do?

I am attempting to test the auth header when doing an api call:

import axios from 'axios';
import ApiClient from './apiClient';
import ApiService from './apiService';

jest.mock('./apiClient', () => {
  return {
    headers: { authorization: 'Bearer test token' },
    get: jest.fn()
  };
});

describe('apiService methods', () => {
  beforeAll(() => {
    ApiClient.get.mockImplementation((url: string) => {
      return Promise.resolve({ data: mockData });
    });
  });

  it('getArticles method call', () => {
    ApiService.getArticles(jest.fn(), 1, 3, 'latest', 'news', 'selectedNews');

    expect(axios.defaults.headers.mon.Authorization).toBe(
      'Bearer test token'
    ); // THIS GIVES UNDEFINED SO THE TEST FAILS

    expect(ApiClient.get).toBeCalledWith(
      '/content?type=article&page=1&limit=3&sort=latest&facet=news&article_category=selectedNews'
    );
  });
});

This is what I have on ApiClient to request the header:

import axios from 'axios';
import envs from '../../config/index.json';

const client = axios.create({
  baseURL: envs.data.data.centralApi.baseUrl + apiVersion
});

client.defaults.headers.mon.Authorization = `Bearer ${localStorage.getItem(
  `adal.access.token.key${envs.data.data.adal.clientId}`
)}`;

So I need to test that the Authorization header is properly send when the api call is performed.

What should I do?

Share Improve this question edited Oct 15, 2019 at 17:41 Non asked Oct 15, 2019 at 17:21 NonNon 8,61920 gold badges80 silver badges130 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

Since ApiService.getArticles is an asynchronous call, you should set your expectations within a then clause.

For example:

  it('getArticles method call', () => {
    ApiService.getArticles(jest.fn(), 1, 3, 'latest', 'news', 'selectedNews').then(() => {
        expect(axios.defaults.headers.mon.Authorization).toBe(
        'Bearer test token'
        ); // THIS GIVES UNDEFINED SO THE TEST FAILS

        expect(ApiClient.get).toHaveBeenCalledWith(
        '/content?type=article&page=1&limit=3&sort=latest&facet=news&article_category=selectedNews'
        );  // Note the use of "toHaveBeenCalledWith" instead of "toBeCalledWith"
    });
});

If your project supports ES6 syntax, you could also use async/await:

it('getArticles method call', async () => {

    await ApiService.getArticles(jest.fn(), 1, 3, 'latest', 'news', 'selectedNews');

    expect(axios.defaults.headers.mon.Authorization).toBe(
      'Bearer test token'
    ); // THIS GIVES UNDEFINED SO THE TEST FAILS

    expect(ApiClient.get).toHaveBeenCalledWith(
      '/content?type=article&page=1&limit=3&sort=latest&facet=news&article_category=selectedNews'
    );

});

You could also use a library like nock to mock HTTP requests in tests.

For instance:

npm install --save-dev nock
import nock from 'nock';
// ...your other imports

const baseUrl = 'https://some-base-url.';
const mockRequest = nock(baseUrl);

describe('apiService methods', () => {

  it('getArticles method call', () => {
    const url = "/content?type=article&page=1&limit=3&sort=latest&facet=news&article_category=selectedNews";

    mockRequest.matchHeader('Authorization', 'Bearer test token').get(url).reply(200, '');

    ApiService.getArticles(jest.fn(), 1, 3, 'latest', 'news', 'selectedNews').then(function (response) { 
        expect(response).to.equal('');
    }).catch((error) => {
        console.log('Incorrect header:', error);
    });

  });

});

If the header doesn't match, an error will be thrown.

One last thing - when you use jest.mock(), you're effectively overriding the file being imported. It's generally meant to override specific methods in the imported file with mock methods. It could be that by overriding apiClient you're not reaching the line of code where you set the default axios headers:

client.defaults.headers.mon.Authorization = `Bearer ${localStorage.getItem(
  `adal.access.token.key${envs.data.data.adal.clientId}`
)}`; // Not being reached because `apiClient` is being overriden

Drop a console log in there to make sure you're getting there.

发布评论

评论列表(0)

  1. 暂无评论