我正在尝试在Angular中测试一个接收日期的服务函数,并检查该日期是否为将来的日期。如果是,则返回true。

// The 'check_date' will always be in the format `dd/mm/yyyy`
public checkDate(check_date: string): boolean {
    const today: any = new Date();
    const dateParts: any = check_date.split('/');
    const dateObject: any = new Date(dateParts[2], dateParts[1] - 1, dateParts[0]);

    if (dateObject.getTime() > today.getTime()) {
        return true;
    }

    return false;
}

我该如何测试?因为如果我做这样的事情:
it('should return true if date is in the future', () => {
    const date = '04/02/2018';
    const result = service.checkDate(date);
    expect(result).toBeTruthy();
});

今天它将过去,因为new Date()将是01/02/2018。但是,如果我下个月运行此测试,它将无法通过。

我可以将日期设置为将来的测试日期,例如01/01/3018。但是我想知道是否还有另一种方法可以测试这种情况。

最佳答案

可以模拟Date以明确测试应该返回的值:

const UnmockedDate = Date;

spyOn(<any>window, 'Date').and.returnValues(
  new UnmockedDate('2018-01-01'),
  new UnmockedDate('2018-02-04')
);

const result = service.checkDate('04/02/2018');

expect(Date).toHaveBeenCalledTimes(2);

expect(Date.calls.all()[0].object instanceof UnmockedDate).toBe(true); // called with new
expect(Date.calls.argsFor(0)).toEqual([]);

expect(Date.calls.all()[1].object instanceof UnmockedDate).toBe(true);
expect(Date.calls.argsFor(1)).toEqual([...]);
...

另外,可以使用Jasmine Clock API模拟日期:
jasmine.clock().install();
jasmine.clock().mockDate('2018-01-01');

const result = service.checkDate('04/02/2018');

...

jasmine.clock().uninstall(); // better be performed in afterEach

由于Date不是 spy ,因此测试不会像可以声明Date调用那样严格。

09-21 00:02