首页 > 解决方案 > 开玩笑 - 如何检测是否调用了模块依赖项中的命名导出?

问题描述

// 依赖.js

export const getFontSize = () => {
    // expensive computation...
};

// 设备.js

import { getFontSize } from './dependancy';
...
const initPxToEm = () => {
    let fontSize;
    return px => {
        if (!fontSize) {
            fontSize = getFontSize();
        }
        return stripUnit(em(px, fontSize));
    };
};
const pxToEm = initPxToEm();
const doSomething = () => pxToEm(window.innerWidth);

我想测试 getFontSize 只被调用一次,即函数被记忆:

// test.js

import device from '../device';
import { getFontSize } from '../dependancy';
jest.mock('../dependancy');

it('should memoize the font size', () => {
    device.doSomething();
    expect(getFontSize).toHaveBeenCalled();
    device.doSomething();
    expect(getFontSize).not.toHaveBeenCalled();
});

但我明白了:

预期的模拟函数不会被调用,但它被调用了:[],[]

标签: javascriptjestjs

解决方案


您应该使用.toHaveBeenCalledTimes(number)来检查该getFontSize函数是否仅被调用一次。此外,您忘记模拟函数的返回值getFontSize,这将导致您的fontSize变量永远不会有一个真正的值(undefined)。所以每次调用device.doSomething()方法都会调用getFontSize被调用的函数。

例如

dependancy.js

export const getFontSize = () => {
  // expensive computation...
};

device.js

import { getFontSize } from './dependancy';

const stripUnit = (val) => val;
const em = (px, fontSize) => px + fontSize;

const initPxToEm = () => {
  let fontSize;
  return (px) => {
    if (!fontSize) {
      fontSize = getFontSize();
    }
    return stripUnit(em(px, fontSize));
  };
};
const pxToEm = initPxToEm();
const doSomething = () => pxToEm(window.innerWidth);

export default { doSomething };

device.test.js

import device from './device';
import { getFontSize } from './dependancy';

jest.mock('./dependancy');

it('should memoize the font size', () => {
  getFontSize.mockReturnValue(16);
  device.doSomething();
  device.doSomething();
  device.doSomething();
  expect(getFontSize).toBeCalledTimes(1);
});

单元测试结果:

 PASS  examples/66557208/device.test.js
  ✓ should memoize the font size (3 ms)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |     100 |      100 |   83.33 |     100 |                   
 dependancy.js |     100 |      100 |       0 |     100 |                   
 device.js     |     100 |      100 |     100 |     100 |                   
---------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.665 s, estimated 4 s

推荐阅读