Angular 5单元测试使用新的日期来检查日期

时间:2018-02-01 23:27:28

标签: javascript angular unit-testing

我试图在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。但是我想知道是否有其他方法来测试这种情况。

3 个答案:

答案 0 :(得分:2)

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不是间谍,因此测试不会像可以声明Date调用的那样严格。

答案 1 :(得分:0)

看看sinon假计时器:
http://sinonjs.org/releases/v4.2.2/fake-timers/

describe('Date.now dependent test', () => {
   let clock; 

   before(() => {
       clock = sinon.useFakeTimers({
          now: 1483228800000
       });
   });

   after(() => {
       clock.restore();
   });

   it('test', () => {
       const now = Date.now();
       //now should always be 1483228800000 here
   });
})

它基于https://github.com/sinonjs/lolex,它覆盖原生Date是一种特殊方式。

答案 2 :(得分:0)

通常我只会修改SUT的输入状态并将其调用一天:

let tomorrow = new Date().addDate(1);
let fnSpy = spyOn(service, 'funcToTest');
expect(fnSpy).toBe(true);

应始终确保在SUT​​中测试的日期大于测试运行时的“今天”日期。

注意:您可能需要将“明天”转换为您的用例的字符串。

希望这会有所帮助。