NestJS服务中基于当前日期设有效期的函数如何用Jest进行单元测试
解决方案
方案1:使用Jest内置假定时器模拟全局时间(推荐)
moment无参调用时默认读取全局Date对象的当前时间,通过Jest的useFakeTimers可以直接模拟全局时间,不需要修改原有业务代码。
测试代码示例:
import { Test, TestingModule } from '@nestjs/testing'; import { YourService } from './your.service'; // 替换为你实际的服务路径 describe('YourService', () => { let service: YourService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [YourService], }).compile(); service = module.get<YourService>(YourService); }); // 每个测试用例执行完恢复真实时间,避免影响其他测试 afterEach(() => { jest.useRealTimers(); }); it('当前日期早于6月1日时,validTo设为当年6月1日', async () => { // 模拟当前时间为2024年5月31日 const mockDate = new Date('2024-05-31'); jest.useFakeTimers().setSystemTime(mockDate); await service.setValidToDate(); // 校验validFrom为模拟的当前日期 expect(userCode.validFrom).toEqual(mockDate); // 校验validTo为2024年6月1日 expect(userCode.validTo.getFullYear()).toBe(2024); expect(userCode.validTo.getMonth()).toBe(5); // month从0计数,5对应6月 expect(userCode.validTo.getDate()).toBe(1); }); it('当前日期晚于等于6月1日时,validTo设为下一年6月1日', async () => { // 模拟当前时间为2024年6月2日 const mockDate = new Date('2024-06-02'); jest.useFakeTimers().setSystemTime(mockDate); await service.setValidToDate(); // 校验validTo为2025年6月1日 expect(userCode.validTo.getFullYear()).toBe(2025); expect(userCode.validTo.getMonth()).toBe(5); expect(userCode.validTo.getDate()).toBe(1); }); });
方案2:单独mock moment模块(不影响全局时间)
如果需要避免修改全局时间影响其他逻辑,可以单独 mock moment 模块的无参调用逻辑:
import moment from 'moment'; import { Test, TestingModule } from '@nestjs/testing'; import { YourService } from './your.service'; // 预mock moment模块 jest.mock('moment', () => { const originalMoment = jest.requireActual('moment'); const mockFn = jest.fn((...args) => { return args.length === 0 ? originalMoment(mockFn.mock.currentDate) : originalMoment(...args); }); mockFn.mock.currentDate = '2024-01-01'; return mockFn; }); describe('YourService', () => { let service: YourService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [YourService], }).compile(); service = module.get<YourService>(YourService); }); it('当前日期早于6月1日时,validTo设为当年6月1日', async () => { // 修改模拟的当前日期 (moment as jest.Mock).mock.currentDate = '2024-05-31'; await service.setValidToDate(); expect(userCode.validTo.getFullYear()).toBe(2024); expect(userCode.validTo.getMonth()).toBe(5); expect(userCode.validTo.getDate()).toBe(1); }); it('当前日期晚于等于6月1日时,validTo设为下一年6月1日', async () => { (moment as jest.Mock).mock.currentDate = '2024-06-02'; await service.setValidToDate(); expect(userCode.validTo.getFullYear()).toBe(2025); expect(userCode.validTo.getMonth()).toBe(5); expect(userCode.validTo.getDate()).toBe(1); }); });
内容的提问来源于stack exchange,提问作者Karry Bee
相关产品推荐
相关产品推荐

