如何使用 Jest 测试身份验证标头?

Posted

技术标签:

【中文标题】如何使用 Jest 测试身份验证标头?【英文标题】:How to test auth headers with 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 标头是否正确发送。

我该怎么办?

【问题讨论】:

【参考方案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

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

【讨论】:

以上是关于如何使用 Jest 测试身份验证标头?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 jest / apollo 客户端中捕获被拒绝的 graphql 订阅?

如何使用身份验证过滤器将标头设置为令牌请求 OAuth?

如何在 ASP.Net 中为一组 Web 请求发送身份验证标头

如何在具有肥皂身份验证标头的 Netbeans 中使用 .NET Web 服务

Android Picasso 库,如何添加身份验证标头?

使用 curl 使用摘要测试基本 http 身份验证