繁体   English   中英

如何使用 Jest 和酶模拟 axios.CancelToken

[英]How to mock axios.CancelToken using Jest and enzyme

我正在尝试对以下模块进行单元测试,但出现以下错误。 有人可以在这里分享有关如何模拟axios.CancelToken()任何想法吗? 或如何测试这部分?

服务.js

let myCancelToken
export async function myTestFuncService (name) {
  if (myCancelToken) {
    myCancelToken.cancel()
  }
  myCancelToken = axios.CancelToken.source()
  try {
    return axios.get(`mypath/${name}`, {
      cancelToken: myCancelToken.token
    })
  } catch (e) {
    return e
  }
}

服务.test.js

import * as myModule from './service.js'
import axios from 'axios'
jest.mock('axios')

it('test myTestFuncService', async () => {
    const testData = {
      data: {
        response: 'some test data'
      }
    }
    axios.get.mockImplementationOnce(() => Promise.resolve(testData))
    await expect(
      myModule.myTestFuncService('ABC')
    ).resolves.toBe(testData)
  })

错误:

TypeError: Cannot set property 'cancel' of undefined

您可以使用jest.spyOn()来模拟axios.CancelToken.source()axios.get()方法。

另外,由于你已经在模块的作用域中定义了变量myCancelToken ,在请求模块并执行myTestFuncService方法后, myCancelToken会被赋值,下次请求模块时,会从request.cache并影响后面的测试用例。 因此,您需要使用jest.resetModules()来清除模块的缓存,以确保不同的测试用例使用“新鲜”模块。

例如

service.js :

import axios from 'axios';

let myCancelToken;
export async function myTestFuncService(name) {
  if (myCancelToken) {
    myCancelToken.cancel();
  }
  myCancelToken = axios.CancelToken.source();
  try {
    return await axios.get(`mypath/${name}`, {
      cancelToken: myCancelToken.token,
    });
  } catch (e) {
    return e;
  }
}

service.test.js :

describe('68673646', () => {
  let mod;
  let axios;
  beforeEach(() => {
    jest.resetModules();
    mod = require('./service');
    axios = require('axios').default;
  });
  afterEach(() => {
    jest.restoreAllMocks();
  });
  test('should get name', async () => {
    const cancelTokenSource = { cancel: jest.fn(), token: { reason: { message: 'user canceled' } } };
    jest.spyOn(axios.CancelToken, 'source').mockReturnValueOnce(cancelTokenSource);
    jest.spyOn(axios, 'get').mockResolvedValueOnce('teresa teng');
    await mod.myTestFuncService('ABC');
    expect(axios.get).toBeCalledWith('mypath/ABC', { cancelToken: cancelTokenSource.token });
    expect(axios.CancelToken.source).toBeCalledTimes(1);
  });

  test('should cancel if cancel token exists', async () => {
    const cancelTokenSource = { cancel: jest.fn(), token: { reason: { message: 'user canceled' } } };
    jest.spyOn(axios.CancelToken, 'source').mockReturnValue(cancelTokenSource);
    jest.spyOn(axios, 'get').mockResolvedValue('teresa teng');
    await mod.myTestFuncService('ABC');
    expect(axios.get).toBeCalledWith('mypath/ABC', { cancelToken: cancelTokenSource.token });
    expect(axios.CancelToken.source).toBeCalledTimes(1);
    await mod.myTestFuncService('DEF');
    expect(cancelTokenSource.cancel).toBeCalledTimes(1);
    expect(axios.get).toBeCalledWith('mypath/DEF', { cancelToken: cancelTokenSource.token });
  });
});

测试结果:

 PASS  examples/68673646/service.test.js (7.34 s)
  68673646
    ✓ should get name (6360 ms)
    ✓ should cancel if cancel token exists (7 ms)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |    87.5 |      100 |     100 |    87.5 |                   
 service.js |    87.5 |      100 |     100 |    87.5 | 14                
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        7.82 s, estimated 8 s

我正在测试 cancelToken 是否可以像这样卸载组件:

`test('Should stop pending request in case the component is unmounted', async () => {
        const { result, unmount } = renderHook(() =>
            // hook goes here
        );

        expect(result.current.cancelTokenSource.token.reason).not.toBeDefined();

        unmount();

        expect(result.current.cancelTokenSource.token.reason).toBeDefined();
    });`

在 cancelToken 被取消后,原因字段被添加到对象中,让我们像这样测试取消。 我们不会嘲笑令牌本身,但这也可能是某些情况下的一种方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM