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

如何在JavaScript单元测试中为Moment.js等外部依赖实现Stub?

测试依赖moment的包装函数与Stub的应用

如何测试verifyPasswordForCurrentDay?

因为verifyPasswordForCurrentDay直接依赖moment(),我们需要用Stub替换moment的实现,让它返回预设的星期几,以此精准控制测试场景。

用Jest实现Stub

先mock整个moment模块,再指定day()方法的返回值:

jest.mock('moment', () => {
  return () => ({
    day: jest.fn()
  });
});

describe("verifyPasswordForCurrentDay", () => {
  test("周末调用时抛出错误", () => {
    const moment = require('moment');
    // 让moment().day()返回周日(0)
    moment().day.mockReturnValue(0);

    expect(() => verifyPasswordForCurrentDay("any input", [])).toThrow(
      "It's the weekend!"
    );
  });

  test("工作日调用时不抛出错误", () => {
    const moment = require('moment');
    // 让moment().day()返回周一(1)
    moment().day.mockReturnValue(1);

    expect(() => verifyPasswordForCurrentDay("any input", [])).not.toThrow();
  });
});

用Mocha+Sinon实现Stub

通过Sinon的stub替换moment.prototype.day的返回值,测试后恢复原方法:

const sinon = require('sinon');
const moment = require('moment');

describe("verifyPasswordForCurrentDay", () => {
  let dayStub;

  beforeEach(() => {
    dayStub = sinon.stub(moment.prototype, 'day');
  });

  afterEach(() => {
    dayStub.restore();
  });

  test("周末调用时抛出错误", () => {
    dayStub.returns(0); // 返回周日
    expect(() => verifyPasswordForCurrentDay("any input", [])).toThrow("It's the weekend!");
  });

  test("工作日调用时不抛出错误", () => {
    dayStub.returns(1); // 返回周一
    expect(() => verifyPasswordForCurrentDay("any input", [])).not.toThrow();
  });
});

关于“测试难题转移”的疑问

这不是转移难题,而是合理的责任拆分:

  • verifyPassword是核心业务逻辑函数,职责是根据输入、规则和日期验证密码。通过参数注入currentDay,让它的测试完全聚焦于业务逻辑,无需关心日期的来源,可全面覆盖周末、工作日、不同规则等场景。
  • verifyPasswordForCurrentDay是适配层函数,职责仅为:获取当前日期,调用核心逻辑并返回结果。它的测试只需验证两点:
    • 正确调用moment().day()获取日期
    • 将日期正确传递给verifyPassword并返回其结果

你无需在这个函数里重复测试“周末抛错”这类业务逻辑——核心逻辑的测试已在verifyPassword中完成。拆分后,每个函数的测试更聚焦,维护成本更低:业务逻辑变更时只需修改verifyPassword的测试;日期获取方式变更时(比如改用原生Date),只需调整verifyPasswordForCurrentDay的测试,两者互不影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 13:36:11