2010-06-28 13 views
6

Actualmente estoy escribiendo una prueba unitaria para un componente que realiza validación específica de fecha y hora. He creado la interfaz IDateTimeProvider, que sirve como una interfaz de uso de wraper y objetos de negocio DateTime.UtcNow en lugar de DateTime directamente. Parece que DateTime está un poco sobrecargado y se debe dividir en un valor y una cosa que obtiene ese valor del sistema operativo. Me pregunto si existe una razón particular para no tener una interfaz IDateTimeProvider (IClock) en .NET.¿Por qué no hay IDateTimeProvider en .NET y DateTime tiene ahora getter?

Respuesta

7

En pocas palabras: porque grandes partes del BCL no fueron diseñadas para la capacidad de prueba.

Lo mismo es cierto para la generación de números aleatorios, en términos de funcionalidad "básica", y muchas de las clases relacionadas con HTTP son mucho más difíciles de falsificar :(Por lo menos en este caso es razonablemente fácil presentar su propio . interfaz de reloj

en el lado positivo, cuando Noda Time está listo para su uso en producción, no sólo proporcionará un mejor API de fecha/hora que el BCL - que va a proporcionar una prueba de una más amigable :)

+0

No olvide, System.IO ... –

1

Utilizamos consistentemente una clase contenedora DateTimeProvider que podemos sobrescribir en un contexto de prueba si es necesario ...

0

http://learn.typemock.com/typemock-isolator/ es capaz de simular DateTime (y otros tipos de mscorlib) así que DateTime.Now no es un problema otra vez. Pero la desventaja es, por supuesto, que esto puede llevar a los desarrolladores a diseñar sus cosas de forma más deficiente, ya que no es ningún problema burlarse de DateTime. ¡Ahora!

Quizás usar algo como IDateTimeProvider es una mejor solución para tales cosas.

Pero si usa una lib de terceros que retransmite, p. DateTime TypeMock-Isolatior puede ser una solución/solución alternativa.

también de Microsoft Research Moles/stub es cosas interesantes: http://channel9.msdn.com/blogs/peli/moles-replace-any-net-method-with-a-delegate (muestra cómo reemplazar cualquier método .NET/propiedad con un delegado - por ejemplo DateTime.Now ;-))

+0

¿Es este enlace? No se puede abrir la página. – Kimi

0

he publicado esta respuesta a otra pregunta, pero se aplica aquí también si está buscando una manera simple de probar DateTime.Now.

Lo que me gusta hacer es crear una función pública que devuelva DateTime (Func<DateTime>) en la clase que necesita la fecha/hora actual y configurarla para que devuelva DateTime.Now de forma predeterminada. Luego, durante la prueba, lo sobreescribo con una función de prueba que devuelve el DateTime con el que quiero probar.

public class MyClass 
{ 
    public Func<DateTime> DateTimeNow =() => DateTime.Now; 

    public void MyMethod() 
    { 
     var currentTime = DateTimeNow(); 
     //... do work 
    } 
} 

public class MyClassTest 
{ 
    public void TestMyMethod() 
    { 
     // Arrange 
     var myClass = new MyClass(); 
     myClass.DateTimeNow =() => new DateTime(1999, 12, 31, 23, 59, 59); 

     // Act 
     myClass.MyMethod(); 

     // Assert 
     // my asserts 
    } 
} 
Cuestiones relacionadas