Jest模拟函数的内部变量和更改函数的行为?

时间:2017-12-28 11:25:08

标签: javascript unit-testing testing jestjs

我对jest的经验很少,因为我试图在我的函数中更改变量,因为如果函数的内部变量(baseUrl)更改为null,我们预计会抛出错误

我的职能:

  

buildUrl.js

  export function buildUrl(contentId, data, options = {}) {
  let baseUrl = config.has('imgBaseUrl') && config.get('imgBaseUrl');
  if (!baseUrl) {
    throw new Error('some error');
  }
...

我需要将baseUrl模拟为null值,例如测试它

  

buildUrl.test.js

import {buildUrl} from "./buildURL";
....
 it('throw an error when "baseUrl" is not configured', () => {

   let mockBaseUrl = {baseUrl: null};
   jest.mock('./buildURL', ()=> mockBaseUrl);
   // jest.mock('../../../config/test', ()=>mockImgBaseUrl); // or mock the config to be used by the function?

   expect(()=> buildUrl('1.44444', data[0], defaultOptions)).toThrow(
     'some error'
   );
   });

使用jest.fn()的另一种方法没有按预期工作,也许我在这里遗漏了一些东西......

2 个答案:

答案 0 :(得分:1)

我认为你可以这样做:

jest.mock('./buildURL', () => {buildUrl: jest.fn()})

buildUrl.mockImplementation(() => {baseUrl: null})

请参阅Jest docs

答案 1 :(得分:0)

这是单元测试解决方案:

baseUrl.js

import config from './config';

export function buildUrl(contentId, data, options = {}) {
  let baseUrl = config.has('imgBaseUrl') && config.get('imgBaseUrl');
  if (!baseUrl) {
    throw new Error('some error');
  }
  console.log(baseUrl);
}

config.js

export default {
  config: {},
  has(key) {
    return !!config[key];
  },
  get(key) {
    return config[key];
  }
};

baseUrl.spec.js

import { buildUrl } from './buildUrl';
import config from './config';

describe('buildUrl', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  it('should throw error when baseUrl is null', () => {
    const defaultOptions = {};
    const data = ['fake data'];
    const hasSpy = jest.spyOn(config, 'has').mockReturnValueOnce(true);
    const getSpy = jest.spyOn(config, 'get').mockReturnValueOnce(null);
    expect(() => buildUrl('1.44444', data[0], defaultOptions)).toThrowError('some error');
    expect(hasSpy).toBeCalledWith('imgBaseUrl');
    expect(getSpy).toBeCalledWith('imgBaseUrl');
  });

  it('should log baseUrl', () => {
    const defaultOptions = {};
    const data = ['fake data'];
    const hasSpy = jest.spyOn(config, 'has').mockReturnValueOnce(true);
    const getSpy = jest.spyOn(config, 'get').mockReturnValueOnce('https://github.com/mrdulin');
    const logSpy = jest.spyOn(console, 'log');
    buildUrl('1.44444', data[0], defaultOptions);
    expect(hasSpy).toBeCalledWith('imgBaseUrl');
    expect(getSpy).toBeCalledWith('imgBaseUrl');
    expect(logSpy).toBeCalledWith('https://github.com/mrdulin');
  });
});

单元测试结果:

 PASS  src/stackoverflow/48006588/buildUrl.spec.js (8.595s)
  buildUrl
    ✓ should throw error when baseUrl is null (9ms)
    ✓ should log baseUrl (7ms)

  console.log node_modules/jest-mock/build/index.js:860
    https://github.com/mrdulin

-------------|----------|----------|----------|----------|-------------------|
File         |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------|----------|----------|----------|----------|-------------------|
All files    |       80 |    83.33 |    33.33 |    77.78 |                   |
 buildUrl.js |      100 |    83.33 |      100 |      100 |                 3 |
 config.js   |    33.33 |      100 |        0 |    33.33 |               4,7 |
-------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        9.768s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/48006588