Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this unit test fail when testing DateTime equality?

Using NUnit 2.2 on .NET 3.5, the following test fails when using DateTime.Equals. Why?

[TestFixture]
public class AttributeValueModelTest
{
    public class HasDate
    {
        public DateTime? DateValue
        {
            get
            {
                DateTime value;
                return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
            }
        }

        public object ObjectValue { get; set; }
    }

    [Test]
    public void TwoDates()
    {
        DateTime actual = DateTime.Now;
        var date = new HasDate {ObjectValue = actual};
        Assert.IsTrue(date.DateValue.Value.Equals(actual));
    }
}
like image 722
flipdoubt Avatar asked Dec 12 '08 20:12

flipdoubt


People also ask

What are the errors commonly found during unit testing?

Unit testing considerations What errors are commonly found during Unit Testing? (1) Misunderstood or incorrect arithmetic precedence, (2) Mixed mode operations, (3) Incorrect initialization, (4) Precision inaccuracy, (5) Incorrect symbolic representation of an expression.

What does the timely rule of unit testing mean?

Timely: Unit tests should be written just before the production code that makes the test pass. This is something that you would follow if you were doing TDD (Test Driven Development), but otherwise it might not apply.

What happens if unit testing is not done?

If any of the unit tests have failed then the QA team should not accept that build for verification. If we set this as a standard process, many defects would be caught in the early development cycle, thereby saving much testing time. I know many developers hate to write unit tests.

Are unit tests run in parallel?

By default, unittest-parallel runs unit tests on all CPU cores available. To run your unit tests with coverage, add either the "--coverage" option (for line coverage) or the "--coverage-branch" for line and branch coverage.


3 Answers

The dates aren't equal. TryParse drops some ticks. Compare the Tick values.

For one test run:

Console.WriteLine(date.DateValue.Value.Ticks);
Console.WriteLine(actual.Ticks);

Yields:

633646934930000000
633646934936763185
like image 50
Amy B Avatar answered Oct 20 '22 00:10

Amy B


The problem isn't really TryParse, but actually ToString().

A DateTime object starts with precision (if not accuracy) down to millionth of seconds. ToString() convertsit into a string, with precision only to a second.

TryParse is doing the best it can with what it is given.

If you add a format specifier (along the lines of "yyyy-MM-dd HH:mm:ss.ffffff"), it should work.

like image 37
James Curran Avatar answered Oct 20 '22 01:10

James Curran


To specify a format that includes all the precision, you can use the String.Format() method. The example that James gives would look like this:

String.Format("{0:yyyy-MM-dd HH:mm:ss.ffffff}", ObjectValue);

I don't know what that will do when you pass it something that's not a date.

Perhaps a simpler approach is to add a special case when you've already got a date object:

    public DateTime? DateValue
    {
        get
        {
            DateTime value = ObjectValue as DateTime;
            if (value != null) return value;
            return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
        }
    }
like image 30
Don Kirkby Avatar answered Oct 20 '22 00:10

Don Kirkby