如何用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
相关产品推荐
相关产品推荐

