简体   繁体   中英

Jest mock function's inner variable and change function's behavior?

i have little experience with jest as i am trying to change variable in my function as we expect to have error thrown if the function's inner variable(baseUrl) changed to null, my function :

buildUrl.js :

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

i need to mock the baseUrl to value of null for example and test it

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

another approach using jest.fn() didnt work as expected , maybe i am missing something here...

I think you can do this:

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

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

See Jest docs

Here is the unit test solution:

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

Unit test result:

 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

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/48006588

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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