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

如何为无返回值函数编写Jest测试用例?以及如何测试获取过去12个月的getDateRange函数?

测试无返回值函数及getDateRange的Jest方案

嘿,我来帮你搞定这两个问题——先聊聊无返回值函数的测试思路,再针对你的getDateRange函数写具体的测试方案。

一、无返回值函数的测试思路

无返回值的函数通常是通过修改外部状态、调用依赖函数、产生副作用(比如控制台输出、DOM操作)来完成工作的,所以测试时不用盯着返回值,而是要关注这些"结果痕迹":

  • 检查它修改的对象/变量是否符合预期(比如你的函数修改了this.months)
  • 用Jest的mock功能,验证它调用的依赖函数是否被正确调用(比如如果函数里调用了fetch,可以mockfetch并检查调用参数)
  • 如果有控制台输出这类副作用,可以监听console.log来验证输出内容

二、针对getDateRange函数的测试方案

首先得先指出你原函数里的几个小问题,不然测试跑不起来:

  1. 循环条件i >= 13是反的,应该是i >= -12(这样才能遍历过去12个月)
  2. push的语法错误,应该是push({ dateLong: previousMonth })
  3. 假设你用的是luxon库的DateTime(因为原生Date没有add方法),我会基于这个修正函数后写测试

修正后的calculateDateRange.js

import { DateTime } from "luxon";

export function getDateRange() {
  const today = new Date();
  this.months = [];
  // 遍历过去12个月(从上个月开始,往前数11个月,共12个)
  for (let i = -1; i >= -12; i--) {
    const previousMonth = DateTime.fromJSDate(today).plus({ months: i });
    const firstDayOfMonth = previousMonth.startOf('month'); // 确保是当月第一天
    if (firstDayOfMonth.year >= 2020) {
      this.months.push({ dateLong: firstDayOfMonth.toJSDate() });
    }
  }
}

编写Jest测试用例

创建calculateDateRange.test.js,核心思路是固定系统时间(避免测试结果随当前时间变化),然后检查this.months的内容是否符合预期:

import { getDateRange } from './calculateDateRange';
import { DateTime } from 'luxon';

// 测试前固定系统时间,避免动态时间影响结果
beforeEach(() => {
  jest.useFakeTimers().setSystemTime(new Date('2023-10-15'));
});

// 测试后恢复真实时间
afterEach(() => {
  jest.useRealTimers();
});

describe('getDateRange', () => {
  it('should generate the last 12 months (starting from previous month) and filter those >=2020', () => {
    // 创建一个对象绑定this,因为函数用this.months存储结果
    const resultObj = {};
    getDateRange.call(resultObj);

    // 生成预期的月份列表:从2022-10-01到2023-09-01,共12个
    const expectedMonths = Array.from({ length: 12 }, (_, index) => {
      const targetMonth = DateTime.fromJSDate(new Date('2023-10-15'))
        .plus({ months: -1 - index })
        .startOf('month');
      return { dateLong: targetMonth.toJSDate() };
    });

    // 比较日期时转成ISO字符串(Date对象直接比较是引用,不准确)
    const actualDates = resultObj.months.map(item => item.dateLong.toISOString());
    const expectedDates = expectedMonths.map(item => item.dateLong.toISOString());
    
    expect(actualDates).toEqual(expectedDates);
  });

  it('should exclude all months before 2020', () => {
    // 固定时间为2019-05-10,此时过去12个月的年份都小于2020
    jest.useFakeTimers().setSystemTime(new Date('2019-05-10'));
    
    const resultObj = {};
    getDateRange.call(resultObj);

    // 预期数组为空,因为所有月份都不符合>=2020的条件
    expect(resultObj.months).toEqual([]);
  });
});

测试要点说明

  • 固定系统时间:用jest.useFakeTimers().setSystemTime()把当前时间固定下来,这样每次测试的输入都是一致的,结果可重复
  • 绑定this:因为你的函数用this.months存储结果,所以需要用call方法把函数绑定到一个空对象上,方便后续检查结果
  • 日期比较技巧:Date对象是引用类型,直接expect(actual).toEqual(expected)会失败,所以转成ISO字符串或者时间戳(getTime())来比较

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 18:47:41