Почему этот модульный тест не проходит при тестировании равенства DateTime?

При использовании NUnit 2.2 в .NET 3.5 следующий тест не выполняется при использовании DateTime.Equals. Почему?

[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));
    }
}
12.12.2008 20:32:51
Просто любопытно, есть ли причина придерживаться NUnit 2.2? 2.8 кажется последним
Perpetualcoder 12.12.2008 20:50:55
Я не прилагаю усилий, чтобы придерживаться 2.2. Это только на моей машине, потому что он поставляется с TestDriven.NET, наряду с 2.4. Что мне не хватает?
flipdoubt 12.12.2008 21:22:29
5 ОТВЕТОВ
РЕШЕНИЕ

Даты не равны. TryParse сбрасывает несколько галочек. Сравните значения тиков.

Для одного пробного запуска:

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

Урожайность:

633646934930000000
633646934936763185
16
12.12.2008 20:43:57
Это заняло у меня немного времени, но я понял это после создания TimeSpan между двумя датами. +1 для вас.
flipdoubt 12.12.2008 20:47:44

Я не знаю, совпадает ли это в .NET, но в Java равенства часто сравниваются, только если экземпляры одинаковы, а не совпадают значения. Вместо этого вы хотели бы использовать сравнение.

0
12.12.2008 20:34:48
Нет, в Java оператор == используется для равенства ссылок, а метод equals () используется для равенства значений.
Adam Rosenfield 12.12.2008 20:35:39
@ Адам: не по умолчанию. Вы должны переопределить метод equals объекта, чтобы получить поведение, которое вы описываете.
Bill the Lizard 12.12.2008 20:38:04
В Советской России == равно Object.Equals
Amy B 12.12.2008 20:51:22
@Адам. При консервативном кодировании вы всегда предполагаете, что это сравнивает экземпляры, потому что это наиболее распространенный случай. Если вы пойдете другим путем, то у вас могут возникнуть проблемы и потребуется время на отладку. Только когда вы точно знаете, вы должны использовать equals ().
Stephane Grenier 12.12.2008 22:02:37

public DateTime? DateValue
        {
            get
            {
                DateTime value;
                bool isDate = DateTime.TryParse(ObjectValue.ToString(), out value); 
                return isDate ? new DateTime?(value) : new DateTime?();
            }
        }

0
12.12.2008 20:37:49
Я не запускал код это чисто на первый взгляд. Прошу прощения, если я не помогу.
shahkalpesh 12.12.2008 20:46:48
Извините, но проблема в TryParse.
flipdoubt 12.12.2008 20:49:18
Спасибо. Когда я посмотрел на код, похоже, что он возвращает DateTime (когда TryParse успешен) вместо DateTime ?. Одна вещь, которую я здесь узнаю, это то, что вы можете назначить экземпляр DateTime DateTime? :)
shahkalpesh 12.12.2008 20:52:45

Проблема не в TryParse, а в самом ToString ().

Объект DateTime начинается с точности (если не с точностью) до миллионной доли секунды. ToString () конвертирует в строку с точностью до секунды.

TryParse делает все возможное с тем, что ему дают.

Если вы добавите спецификатор формата (вдоль строк "yyyy-MM-dd HH:mm:ss.ffffff"), он должен работать.

3
12.12.2008 21:16:00
Хм, Object.ToString () не принимает спецификатор формата. Какие-либо предложения?
flipdoubt 12.12.2008 21:40:56

Чтобы указать формат, который включает в себя всю точность, вы можете использовать метод String.Format (). Пример, который приводит Джеймс, будет выглядеть так:

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

Я не знаю, что это будет делать, когда вы передадите что-то, что не является свиданием.

Возможно, более простой подход - добавить специальный случай, когда у вас уже есть объект даты:

    public DateTime? DateValue
    {
        get
        {
            DateTime value = ObjectValue as DateTime;
            if (value != null) return value;
            return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
        }
    }
1
12.12.2008 22:36:18