2008-12-12 12 views
6

Al usar NUnit 2.2 en .NET 3.5, la siguiente prueba falla al usar DateTime.Equals. ¿Por qué?¿Por qué falla esta prueba de unidad cuando se prueba la igualdad de DateTime?

[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)); 
    } 
} 
+0

Sólo por curiosidad, alguna razón para pegarse a NUnit 2.2 ?? 2.8 parece ser el último – Perpetualcoder

+0

No estoy haciendo un esfuerzo para seguir con 2.2. Está solo en mi máquina porque viene con TestDriven.NET, junto con 2.4. ¿Qué me estoy perdiendo? – flipdoubt

Respuesta

14

Las fechas no son iguales. TryParse deja caer algunas marcas. Compare los valores de Tick.

por prueba:

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

Los rendimientos:

633646934930000000 
633646934936763185 
+0

Me tomó un poco, pero lo descubrí después de crear un TimeSpan entre las dos fechas. +1 para ti. – flipdoubt

+0

+1 a usted por pensar y saber eso! – Perpetualcoder

0

No sé si esto es lo mismo en .NET, pero en Java iguales a menudo sólo se comparará si los casos son los mismos, no se si los valores son los mismos. En cambio, querrías usar compareTo.

+0

No, en Java, el operador == se usa para la igualdad de referencia y el método equals() se usa para la igualdad de valores. –

+0

@ Adam: No de forma predeterminada. Debe sobrescribir el método de Iguales del Objeto para obtener el comportamiento que está describiendo. –

+0

en la Rusia soviética, == es igual a Object.Equals –

0
 

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

No he ejecutado el código. esto está basado puramente en la mirada. Lo siento, si no soy de ayuda. – shahkalpesh

+0

Lo sentimos, pero es TryParse ese el problema. – flipdoubt

+0

Gracias. Cuando miré el código, parece que está devolviendo DateTime (cuando TryParse es exitoso) en lugar de DateTime ?. Una cosa que aprendo aquí es que puede asignar una instancia de DateTime a DateTime. :) – shahkalpesh

3

El problema no es realmente TryParse, pero en realidad ToString().

Un objeto DateTime comienza con precisión (si no es preciso) hasta millonésimas de segundos. ToString() lo convierte en una cadena, con precisión solo en un segundo.

TryParse está haciendo lo mejor que puede con lo que se le da.

Si agrega un especificador de formato (a lo largo de las líneas de "yyyy-MM-dd HH:mm:ss.ffffff"), debería funcionar.

+0

Hmmm, Object.ToString() no toma un especificador de formato. ¿Alguna sugerencia? – flipdoubt

1

Para especificar un formato que incluya toda la precisión, puede utilizar el método String.Format(). El ejemplo que se da a James sería el siguiente:

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

no sé lo que va a hacer cuando se le pasa algo que no es una cita.

Tal vez un método más sencillo es añadir un caso especial cuando ya tienes un objeto de fecha:

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