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

季节判断函数测试失败:伪造Date对象场景未抛出指定错误

问题:伪造Date对象导致getSeason函数校验失效

我实现了一个根据输入日期判断季节的getSeason函数,大部分测试用例都能通过,但在一个伪造Date对象的测试用例中失败了。该测试用例创建了一个设置了Date原型、Symbol.toStringTag为'Date'的伪造对象,要求函数抛出"Invalid date!"错误,但当前函数未满足要求,返回actual: false; expected: true。

编写的函数代码

function getSeason(date) {
  const isValidDate = (d) => {
    return d instanceof Date && !isNaN(d);
  };
  let season = "";
  if (date === undefined) return "Unable to determine the time of year!";
  if (!isValidDate(date)) throw new Error("Invalid date!");

  const springStart = new Date(date.getFullYear(), 2, 1);
  const summerStart = new Date(date.getFullYear(), 5, 1);
  const autumnStart = new Date(date.getFullYear(), 8, 1);
  const winterStart = new Date(date.getFullYear(), 11, 1);

  if (date >= springStart && date < summerStart) {
    season = "spring";
  } else if (date >= summerStart && date < autumnStart) {
    season = "summer";
  } else if (date >= autumnStart && date < winterStart) {
    season = "autumn";
  } else if (date >= winterStart && date < springStart) {
    season = "winter";
  } else {
    return "winter";
  }
  return season;
}

失败的测试用例

it.optional('throws an error with message "Invalid date!" on tricky moment', function () {
  const fakeDate = {
    toString() {
      return Date.prototype.toString.call(new Date());
    },
    [Symbol.toStringTag]: 'Date'
  };

  Object.setPrototypeOf(fakeDate, Object.getPrototypeOf(new Date()));

  const res = checkForThrowingErrors.call(this, [
    () => getSeason(fakeDate)
  ], 'Invalid date!');

  assert.strictEqual(res.every($ => $ === CORRECT_RESULT_MSG), true);
});

问题分析与解决方法

问题根源

当前的isValidDate函数使用d instanceof Date && !isNaN(d)进行校验:

  • d instanceof Date会被伪造对象绕过,因为测试用例给对象设置了Date原型;
  • !isNaN(d)仅判断对象转换为数字是否有效,伪造对象可通过重写valueOf方法返回有效数字来绕过,此时函数会继续执行后续代码,调用date.getFullYear()等方法时,由于伪造对象没有Date实例的内部时间值,会抛出非预期错误或返回无效值,导致测试失败。

解决方法

修改isValidDate函数,使用d.getTime()来判断日期有效性——真正的有效Date实例调用getTime()会返回时间戳数字,无效Date实例和伪造对象调用getTime()都会返回NaN:

const isValidDate = (d) => {
  return d instanceof Date && !isNaN(d.getTime());
};

修改后的函数会正确识别伪造对象,抛出"Invalid date!"错误,满足测试用例要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 01:55:20