Stubbing new Date

2,094 views
Skip to first unread message

Alex Moore

unread,
Dec 13, 2011, 4:52:58 AM12/13/11
to Jasmine
Hey Guys,

I have the following function

testSomething: function() {
var dateTimeNow = new Date();
return dateTimeNow;
}

and i'd like to use the spyOn function to stub out the date and return
a particular date time so that I can test date specific conditions. I
can't work out how to do it.

cheers

Alex

Davis Frank

unread,
Dec 13, 2011, 11:39:45 AM12/13/11
to jasmi...@googlegroups.com
This is the "how do I spy on Constructors" problem.

You can:

spyOn(window, 'Date').andCallThrough()

But that won't give you a Date object.

So what I often do with date is work with milliseconds everywhere. Have a getTime() function that returns Date.now(), which is millis since epoch. 

So

function getTime() {
return Date.now()
}

..and

new Date(getTime())

Under test:

spyOn(window, 'getTime').andReturn(<some ms value)

--dwf



Alex

--
You received this message because you are subscribed to the Google Groups "Jasmine" group.
To post to this group, send email to jasmi...@googlegroups.com.
To unsubscribe from this group, send email to jasmine-js+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/jasmine-js?hl=en.


Doug Reeder

unread,
Dec 13, 2011, 12:27:09 PM12/13/11
to jasmi...@googlegroups.com
Is the problem with spying on Constructors, that not every JS implementation allows setting __proto__ ?



-- Sent from my Palm Pre 2


Rajan Agaskar

unread,
Dec 13, 2011, 1:12:22 PM12/13/11
to jasmi...@googlegroups.com
The trickiness, IIRC, is that most people want to use spies to return an instance from a new-ed constructor, but that is not an easy thing. 

IE, people want to do something like: 

foo = new Foo();
//manipulate foo
spyOn(window, "Foo").and_return(foo); 

due to the way "new" works, this won't get you what you want. 

Last time I thought about this problem there was a complicated workaround with andCallFake that would work with the 80% case (essentially you return your instance from function passed to andCallFake). We may at some point add a spyOnConstructor method or something similar. If there is a trick with __proto__ that would make this simpler, let us know! 

Thanks!

Rajan 

Alex Moore

unread,
Dec 14, 2011, 12:56:43 AM12/14/11
to Jasmine
ok thanks guys i've tried that with:
var testDate = 'fasdfsadf';
spyOn(MyApp.util, 'now').andReturn(testDate);

testDate = new Date('2011-01-01 03:00');
expect(session.endOfDay()).toEqual(new Date('2011-01-02 00:00'));

testDate = new Date('2011-01-01 05:00');
expect(session.endOfDay()).toEqual(new Date('2011-01-02 00:00'));

testDate = new Date('2011-01-01 23:59')
expect(session.endOfDay()).toEqual(new Date('2011-01-02 00:00'));

The issue i'm getting now is that you can only use the spyOn function
once (i can't replace it 4 times in a row, and that when i pass
testDate into andReturn you can no longer change the variable (i.e
it's then bound).

Is my only option to split this 1 test into 4 different tests?

Ben Loveridge

unread,
Dec 14, 2011, 1:02:13 AM12/14/11
to jasmi...@googlegroups.com
You can do this:

spyOn(obj, "method").andReturn(val1);
// test stuff
obj.method.andReturn(val2);
// test more stuff
obj.method.andReturn(val3);
--
Ben Loveridge

Alex Moore

unread,
Dec 14, 2011, 1:12:07 AM12/14/11
to Jasmine
worked it out :)


var testDate = 'creating closure to use this later';
var dateFunc = function() {
return testDate;
}
spyOn(MyApp.util, 'now').andCallFake(dateFunc)

Rob Hunter

unread,
Dec 14, 2011, 9:36:59 AM12/14/11
to jasmi...@googlegroups.com

The library Timecop.js might be of interest.

https://github.com/jamesarosen/Timecop.js

It provides controllable Date behaviour.

--
Rob Hunter
(typed with my thumbs)

Reply all
Reply to author
Forward
0 new messages