NUnit Assert.AreEqual DateTime Tolerances
Asked Answered
R

3

75

I'm wondering if anybody's found a good solution to this:

In our unit tests; we commonly use Assert.AreEqual() to validate our results. All is well and good; until we start trying to use this on DateTime properties.

Although the times are very similar, sometimes they are off by milliseconds, which causes the tests to fail. In our application; as long as they're accurate to the second; that's good enough for us.

Has anybody found a good way to somehow implement tolerances in this case? Typically our workaround is to split it into 2 separate statements; one which checks the .ToShortDateString(), and another that checks .ToShortTimeString(), but this looks sloppy in my opinion.

Riane answered 26/8, 2010 at 17:42 Comment(0)
E
99

You can check tolerances with something like:

Debug.Assert((date1 - date2) < TimeSpan.FromSeconds(1));

If you are unsure which date is newer, use

Debug.Assert(Math.Abs((date1 - date2).TotalSeconds) < 1)

NUnit has also added built in support for this using the Within keyword

DateTime now = DateTime.Now;
DateTime later = now + TimeSpan.FromHours(1.0);

Assert.That(later, Is.EqualTo(now).Within(TimeSpan.FromHours(3.0)));
Assert.That(later, Is.EqualTo(now).Within(3).Hours);
Edmundoedmunds answered 26/8, 2010 at 17:49 Comment(5)
Very nice. Never thought to implement it this wayRiane
But don't you really mean <?Rauch
@Dan Tao - Yeah, had my assert thinking was backward, yeah if u want it to error, then it should <Edmundoedmunds
This will fail if date2 is larger than date1 by more than a second. Should check the absolute value of the total seconds of the difference. e.g. Debug.Assert(Math.Abs((date1 - date2).TotalSeconds) < 1)Yiyid
NUnit has in-built support for this, see my answer below #3578356Tonsillectomy
T
110

Use Assert.That and Is.Equal constraint instead of Assert.AreEqual. Below is a code sample from the Nunit website itself

DateTime now = DateTime.Now;
DateTime later = now + TimeSpan.FromHours(1.0);

Assert.That(now, Is.EqualTo(now) );
Assert.That(later, Is.EqualTo(now).Within(TimeSpan.FromHours(3.0)));
Assert.That(later, Is.EqualTo(now).Within(3).Hours);
Tonsillectomy answered 29/9, 2011 at 18:5 Comment(3)
Much cleaner solution. If this Assert fails, the message produced will clearly indicate the cause of the failure.Tabatha
Why use Assert.That instead of Assert.AreEqual? Could you give some explanation?Pieper
@Pieper check out the discussion at https://mcmap.net/q/270379/-assert-that-vs-assert-true Assert.That give you more extensibility and better logging if done correctly.Mandamandaean
E
99

You can check tolerances with something like:

Debug.Assert((date1 - date2) < TimeSpan.FromSeconds(1));

If you are unsure which date is newer, use

Debug.Assert(Math.Abs((date1 - date2).TotalSeconds) < 1)

NUnit has also added built in support for this using the Within keyword

DateTime now = DateTime.Now;
DateTime later = now + TimeSpan.FromHours(1.0);

Assert.That(later, Is.EqualTo(now).Within(TimeSpan.FromHours(3.0)));
Assert.That(later, Is.EqualTo(now).Within(3).Hours);
Edmundoedmunds answered 26/8, 2010 at 17:49 Comment(5)
Very nice. Never thought to implement it this wayRiane
But don't you really mean <?Rauch
@Dan Tao - Yeah, had my assert thinking was backward, yeah if u want it to error, then it should <Edmundoedmunds
This will fail if date2 is larger than date1 by more than a second. Should check the absolute value of the total seconds of the difference. e.g. Debug.Assert(Math.Abs((date1 - date2).TotalSeconds) < 1)Yiyid
NUnit has in-built support for this, see my answer below #3578356Tonsillectomy
Y
10

To correctly check if any 2 arbitrary dates are equals to within a 1 second tolerance, the following is a correct solution:

Debug.Assert(Math.Abs((date1 - date2).TotalSeconds) < 1)

I figured I'd add this as a solution since the accepted solution was incorrect when date2 is larger than date1 by more than a second, and the solution has not been updated following my comment to @SwDevMan81.

Yiyid answered 26/8, 2010 at 22:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.