我试图在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
。但是我想知道是否有其他方法来测试这种情况。
答案 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中测试的日期大于测试运行时的“今天”日期。
注意:您可能需要将“明天”转换为您的用例的字符串。
希望这会有所帮助。