In a pinch - legacy app for example - you can use virtualization and "really"
change the virtual clock.
Hi Simone
> I never heard of Moles nor JustMock, nice to see so many tools popping up, although I'm not a fan of such mock-everything tools.
Moles is part of the Pex package developed by Microsoft
JustMock is actually very new, its developed by Telerik and its beta was announced just a couple of weeks ago middle of April.
from what I saw it still has some way to go, but it looks like it is going in a good direction.
Lior
Sadly Simone, the link to the PDF file on the virtual clock page is
broken... don't know if anyone might have that PDF file stashed away.
I think I've done something that might be fairly similar, but I want
to see what others have done before tainting the discussion with what
I've come up with. The stuff I've been working on lately is hard for a
few reasons.
1) I discovered today that the DateTime class is not very good at
dealing with UTC.
2) multiple threading makes all of this more difficult.
3) Wanting tests to be consistent from one run to the next is
impossible in a randomnized time environment simulating randomness in
things like how long it takes an HTTP page to download.
I've had to resort to logging and pouring over pages of logs to figure
out what's going on. Pulling hair.
-Kelly
> --
> You received this message because you are subscribed to the Google Groups
> "NUnit-Discuss" group.
> To post to this group, send email to nunit-...@googlegroups.com.
> To unsubscribe from this group, send email to
> nunit-discus...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/nunit-discuss?hl=en.
>
>
--
Sent from my mobile device
What you need is a mocking framework that can handle DateTime.
Typemock Isolator - can handle mocking of DateTime.Now but that’s about it
for now.
JustMock - claims to be able to mock all types from mscorlib, including
DateTime.
And there's also a chance that MS-Moles might be able to do that.
Lior Friedman
Blog - http://imistaken.blogspot.com
Thanks Al, this is nearly identical to what I had come up with, adding
the Jump Forward feature mentioned in one of the comments. I was
curious if anyone else had come up with a similar idea, and there it
is. Kind of validating to see a similar solution.
I really liked the idea of searching the metadata for uses of
DateTime.Now... you wouldn't happen to have source for that test would
you?
One thing that I added which was really important to the code I am
building was an alternative implementation of Thread.Sleep. I'll
explain it here in case anyone needs a similar function in the future.
If you call Thread.Sleep(1000), then jump your virtual clock forward 5
minutes, the thread would actually sleep for 5 minutes and one second
in the time line of the test. This can cause bad things to happen, so
I implemented a sleep function inside the virtual time class like
this:
public void Sleep(int milliseconds)
{
DateTime sleepUntil = _baseTime + new TimeSpan(0, 0, 0, 0,
milliseconds);
// if Now jumps ahead, then the sleep ends immediately.
while(sleepUntil < Now)
{
Thread.Sleep(10);
}
}
public DateTime Now
{
get
{
TimeSpan span = DateTime.UtcNow - _start;
return _baseTime + span;
}
}
This isn't a perfect solution as the Sleep doesn't REALLY end prior to
the five minutes, but it worked well enough for me at this time. I
suppose the jump forward could take into account that there are
pending sleeps, and "wake up" for a time to get those sleeps to end at
the proper time, but that's YAGNI for me at this point. It took me
quite a while to deduce the interaction between Jump Forward and Sleep
in my multithreaded mess. :-) So hopefully, this will be helpful to
someone in a similar situation in the future.
I am doing all my times in UTC time, which simplifies things, but I
strongly recommend that you do characterization tests on how DateTime
deals with UTC until you have a very firm grasp of how it's dealt with
because it is highly unintuitive (at least to me).
For me, these included the following:
[Test]
public void WhyTheCrapDoesThisPass()
{
var time1 = new DateTime(2010, 01, 01, 8, 0, 0, DateTimeKind.Local);
var time2 = new DateTime(2010, 01, 01, 8, 0, 0, DateTimeKind.Utc);
// REALLY!!!!
Assert.That(time1 == time2, string.Format("time1:{0}
time2:{1}", time1, time2));
}
private const string aDate = "Mon, 14 Jun 2010 16:08:02 GMT";
[Test]
public void ThisIsHowItIsDone()
{
DateTime time = Convert.ToDateTime(aDate);
time = time.ToUniversalTime();
string str = String.Format("{0:r}", time); // "Sun, 09
Mar 2008 16:05:07 GMT" RFC1123
Assert.That(str, Is.EqualTo(aDate));
}
-Kelly
>> > nunit-discus...@googlegroups.com<nunit-discuss%2Bunsu...@googlegroups.com>
>> .
>> > For more options, visit this group at
>> > http://groups.google.com/group/nunit-discuss?hl=en.
>> >
>> >
>>
>> --
>> Sent from my mobile device
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "NUnit-Discuss" group.
>> To post to this group, send email to nunit-...@googlegroups.com.
>> To unsubscribe from this group, send email to
>> nunit-discus...@googlegroups.com<nunit-discuss%2Bunsu...@googlegroups.com>
> For me, these included the following:
>
> [Test]
> public void WhyTheCrapDoesThisPass()
> {
> var time1 = new DateTime(2010, 01, 01, 8, 0, 0, DateTimeKind.Local);
> var time2 = new DateTime(2010, 01, 01, 8, 0, 0, DateTimeKind.Utc);
> // REALLY!!!!
> Assert.That(time1 == time2, string.Format("time1:{0}
> time2:{1}", time1, time2));
> }
In .Net 3.5 they have added a new class called DateTimeOffset
http://www.danrigsby.com/blog/index.php/2008/08/23/datetime-vs-datetimeoffset-in-net/
Using DateTimeOffset, things make a little more sense (to me anyway).
[Test]
public void SLCandSFO()
{
// one hour later in Salt Lake than in San Francisco
var sfo = new DateTimeOffset(2010, 01, 01, 9, 0, 0, new
TimeSpan(-8, 0, 0));
Console.WriteLine(sfo);
var slc = new DateTimeOffset(2010, 01, 01, 10, 0, 0, new
TimeSpan(-7, 0, 0));
Console.WriteLine(slc);
//Assert.That(sfo.CompareTo(slc), Is.EqualTo(0));
Assert.That(sfo - slc, Is.EqualTo(new TimeSpan(0, 0, 0)));
Assert.That(sfo,Is.EqualTo(slc), string.Format("time1:{0}
time2:{1}", sfo,slc));
}
So anyone stumbling into this in the future will have one more piece
of the puzzle...
-Kelly