47

my C# unit test has the following statement:

Assert.AreEqual(logoutTime, log.First().Timestamp);

Why it is failed with following information:

Assert.AreEqual failed. Expected:<4/28/2010 2:30:37 PM>. Actual:<4/28/2010 2:30:37 PM>.

Are they not the same?

Update:

Use this if you only care to second:

Assert.AreEqual(logoutTime.ToString(), log.First().Timestamp.ToString());

abatishchev
  • 98,240
  • 88
  • 296
  • 433
5YrsLaterDBA
  • 33,370
  • 43
  • 136
  • 210
  • 13
    Are you sure the two values are equal? Maybe the millisecond parts are different? – dtb Apr 28 '10 at 18:37
  • 1
    Check out http://stackoverflow.com/questions/364055/why-does-this-unit-test-fail-when-testing-datetime-equality apparently while the dates are equal that doesn't mean they are equal down to the tick. – Rangoric Apr 28 '10 at 18:38

9 Answers9

44

Have you verified that the number of ticks/milliseconds are equal?

If you do DateTime.Now() twice back to back, they will appear to be the same number down to the minute and probably even down to the second, but they will often vary by ticks. If you want to check equality only to the minute, compare each DateTime only to that degree. For information on rounding DateTimes, see here


A note about resolution:

The Now property is frequently used to measure performance. However, because of its low resolution, it is not suitable for use as a benchmarking tool. A better alternative is to use the Stopwatch class.

Community
  • 1
  • 1
Dinah
  • 52,922
  • 30
  • 133
  • 149
4

Try something like Assert.AreEqual(logoutTime.Ticks, log.First().Timestamp.Ticks)

Germ
  • 6,360
  • 4
  • 26
  • 26
  • As Jon Skeet says on jlech's answer: "That will do exactly the same thing, other than showing the different values of ticks in the exception message." – Dinah Apr 28 '10 at 19:16
  • 1
    Exactly, so it will show you why the two values aren't equal. – Germ Apr 28 '10 at 20:08
4

The Assert fail method is probably calling ToString() on the DateTime which returns a truncated, human-readable form of the date without the milliseconds component. This is why it appears they are equal when, in fact, the DateTime object has a precision of a 100-nanosecond unit (known as a Tick). That means it is highly unlikely two DateTime objects will have the exact same value. To compare you probably want to truncate the value, perhaps by formatting the date to the fidelity you require.

Dan Diplo
  • 25,076
  • 4
  • 67
  • 89
2

Using entity framework, if you fetch from the database using .AsNoTracking() the DateTime property will be rounded ever so slightly, whereas it won't necessarily be rounded without .AsNoTracking() if the original value is still in memory. Thus for integration tests involving a round-trip to the database, I guess it's best to use .ToString() because the database will reduce the precision slightly.

Matthew
  • 4,149
  • 2
  • 26
  • 53
1

Are you sure that logoutTime and log.First().Timestamp are both typed as DateTime?

If so, they might also have different values for the more specific time infomation (e.g., milliseconds).

reustmd
  • 3,513
  • 5
  • 30
  • 41
0

Assuming that logoutTime and log.First().Timestamp are both of type DateTime, you should try using this instead:

Assert.AreEqual(logoutTime.Ticks, log.First().Timestamp.Ticks);
John Lechowicz
  • 2,573
  • 3
  • 21
  • 34
  • 1
    That will do exactly the same thing, other than showing the different values of ticks in the exception message. – Jon Skeet Apr 28 '10 at 18:46
0

While working on unit test, I found below steps very useful to compare some date with mock date.

Mock date field as below:

mockDate = new DateTime(2020, 10, 10)

Call service method.

Assertion can be done like this:

Assert.AreEqual("10/10/2020 12:00:00 AM", _service.startDate.ToString());

Note while doing assertion:

  • We have to provide date like : 10/10/2020 12:00:00 AM
  • Then on service method date item we need to apply ToString(), this will convert date time into string value for comparison

If we just have to do assertion with datetime today date

Assert.AreEqual(DateTime.Today, _service.startDate);
Manish Kumar
  • 191
  • 1
  • 9
0

Since 2018 XUnit supports DateTime comparison within a given precision:

Assert.Equal(DateTime.Now, myObject.CreatedAt, TimeSpan.FromSeconds(1));
maccaroo
  • 819
  • 2
  • 12
  • 22
-1

I suppose Assert.AreEqual<T> uses Object.Equals() to determine equality of the objects but not the values.

Probably this statement is comparing two different objects and therefore is returning false.

Dinah
  • 52,922
  • 30
  • 133
  • 149
Asad
  • 21,468
  • 17
  • 69
  • 94