You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Jest为返回值相同的if-else函数编写单元测试

使用Jest测试函数分支调用的解决方案

问题描述

我编写了如下TypeScript函数,需要用Jest做单元测试:

export const functionToTest=(condition:boolean)=>{
  if(condition){
    return getDataFromCache()
  }
  else{
    return getDataFromApi()
  }
}

要求确保传入不同的condition参数时,对应的getDataFromCache或getDataFromApi函数被正确调用。但这两个子函数返回值完全相同,没法通过校验返回值来判断分支逻辑是否正确,该怎么处理?

解决方案

核心思路是用Jest模拟(Mock)依赖函数,追踪它们的调用状态,不需要依赖返回值就能验证分支逻辑。以下是具体实现方式:

方法1:通过jest.mock模拟整个模块的依赖函数

假设getDataFromCache和getDataFromApi与functionToTest在同一个文件中,测试代码可以这样写:

import { functionToTest, getDataFromCache, getDataFromApi } from './your-module-path';

// 保留原模块其他导出,仅模拟目标函数
jest.mock('./your-module-path', () => ({
  ...jest.requireActual('./your-module-path'),
  getDataFromCache: jest.fn(),
  getDataFromApi: jest.fn(),
}));

describe('functionToTest', () => {
  // 每次测试前清空函数调用记录
  beforeEach(() => {
    jest.clearAllMocks();
  });

  test('当condition为true时,仅调用getDataFromCache', () => {
    functionToTest(true);
    // 断言缓存函数被调用1次
    expect(getDataFromCache).toHaveBeenCalledTimes(1);
    // 断言API函数未被调用
    expect(getDataFromApi).not.toHaveBeenCalled();
  });

  test('当condition为false时,仅调用getDataFromApi', () => {
    functionToTest(false);
    expect(getDataFromApi).toHaveBeenCalledTimes(1);
    expect(getDataFromCache).not.toHaveBeenCalled();
  });
});

方法2:用jest.spyOn单独模拟目标函数

如果不想模拟整个模块,也可以用spyOn单独监听目标函数:

import * as targetModule from './your-module-path';
import { functionToTest } from './your-module-path';

describe('functionToTest', () => {
  let cacheSpy: jest.SpyInstance;
  let apiSpy: jest.SpyInstance;

  // 测试前创建模拟函数,可自定义返回值(这里返回相同值不影响测试)
  beforeEach(() => {
    cacheSpy = jest.spyOn(targetModule, 'getDataFromCache').mockReturnValue('any-value');
    apiSpy = jest.spyOn(targetModule, 'getDataFromApi').mockReturnValue('any-value');
  });

  // 测试后恢复原函数,避免影响其他测试
  afterEach(() => {
    jest.restoreAllMocks();
  });

  test('condition为true时触发缓存调用', () => {
    functionToTest(true);
    expect(cacheSpy).toHaveBeenCalled();
    expect(apiSpy).not.toHaveBeenCalled();
  });

  test('condition为false时触发API调用', () => {
    functionToTest(false);
    expect(apiSpy).toHaveBeenCalled();
    expect(cacheSpy).not.toHaveBeenCalled();
  });
});

关键说明

Jest的mock函数会自动记录调用次数、调用参数等信息,我们不需要关心函数的实际返回值,直接通过toHaveBeenCalled、toHaveBeenCalledTimes这类断言方法,就能验证分支逻辑是否正确触发了对应的函数。

内容的提问来源于stack exchange,提问作者Hrishagni De

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:25:21