【问题标题】:How to test auth headers with Jest?如何使用 Jest 测试身份验证标头?
【发布时间】:2020-02-12 10:27:15
【问题描述】:

我正在尝试在进行 api 调用时测试 auth 标头:

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

这是我在ApiClient 上请求标头的内容:

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

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

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

所以我需要在执行 api 调用时测试 Authorization 标头是否正确发送。

我该怎么办?

【问题讨论】:

    标签: javascript reactjs unit-testing ecmascript-6 jestjs


    【解决方案1】:

    由于ApiService.getArticles 是一个异步调用,您应该在then 子句中设置您的期望。

    例如:

      it('getArticles method call', () => {
        ApiService.getArticles(jest.fn(), 1, 3, 'latest', 'news', 'selectedNews').then(() => {
            expect(axios.defaults.headers.common.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"
        });
    });
    
    

    如果你的项目支持 ES6 语法,你也可以使用async/await:

    it('getArticles method call', async () => {
    
        await ApiService.getArticles(jest.fn(), 1, 3, 'latest', 'news', 'selectedNews');
    
        expect(axios.defaults.headers.common.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'
        );
    
    });
    
    

    您还可以使用 nock 之类的库在测试中模拟 HTTP 请求。

    例如:

    npm install --save-dev nock
    
    import nock from 'nock';
    // ...your other imports
    
    const baseUrl = 'https://some-base-url.com';
    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);
        });
    
      });
    
    });
    
    

    如果头部不匹配,则会抛出错误。

    最后一件事 - 当您使用 jest.mock() 时,您实际上覆盖了正在导入的文件。它通常意味着使用模拟方法覆盖导入文件中的特定方法。可能是通过覆盖apiClient,您没有到达设置默认axios 标头的代码行:

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

    将控制台登录到那里以确保您到达那里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-28
      • 2021-06-19
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      相关资源
      最近更新 更多