2011-02-23 18 views
7

¿Cuál sería la prueba junit ser cuando tengo el siguiente método:Junit con new Date()

@Override 
public void saveLastSuccesfullLogin(final User user) { 
    gebruiker.setLastLogin(new Date()); 
    storeUser(user); 
} 

submethode storeUser:

@Override 
public void storeUser(final User user) { 
    EntityManager em = emf.createEntityManager(); 

    em.getTransaction().begin(); 
    em.merge(user); 
    em.getTransaction().commit(); 

    em.close(); 
} 

El problema que tengo es la fecha, se establece para el usuario de la entidad y luego almacenado. Estoy usando junit y easymock.

Respuesta

4

Trate tirando de la nueva fecha() en un método de acceso predeterminado especificador, como a continuación

@Override 
public void saveLastSuccesfullLogin(final User user) { 
    gebruiker.setLastLogin(getDate()); 
    storeUser(user); 
} 
Date getDate() { 
    return new Date(); 
} 

En años Tu clase de prueba anula la clase de la siguiente manera usando una fecha simulada o aplazada.

<ClassUnderTest> classUnderTest = new <ClassUnderTest>() { 
    @Override 
    Date getDate() { 
    return mockDate; 
    } 
} 

De esta manera puede afirmar el valor de la fecha fácilmente, ya que se apagará.

+2

en lugar de anular con la clase anónima usaría [la simulación parcial de Mockito] (http://blog.javabien.net/2009/06/21/mockitos-partial-mocks-testing-real-objects-just-got- más fácil/). Entonces, sería ClassUnderTest t = spy (new ClassUnderTest()); cuando (t.getDate()).thenReturn (DATE_MOCK); –

+0

@ SauliusŠimčikas Gracias por señalar –

3

¿Cuál es el problema con la fecha? ¿Que no sabes qué es afirmar después? Unas pocas alternativas:

  1. pase la fecha en el método
  2. Crear una fábrica para obtener la fecha/hora actual para que pueda burlarse fuera
  3. valer la fecha dentro de un umbral de corrección
0

También hay un enfoque más "empresarial" que se puede utilizar cuando la Inyección de Dependencia está disponible (como en EJB, Primavera, etc.).

Puede definir una interfaz, por ejemplo TimeService y agregar un método que devuelve la fecha actual.

public interface TimeService { 
    Date getCurrentDate(); 
    } 

se puede implementar esta para volver new Date() y utilizar de esta manera:

gebruiker.setLastLogin(timeService.getCurrentTime()); 

Esta será, evidentemente, muy fácil de probar, ya que puede burlarse de la TimeService. Usando EasyMock (es un ejemplo), esto podría ser:

Date relevantDateForTest = ... 
    expect(timeService.getCurrentTime()).andReturn(relevantDateForTest); 
    replay(timeService); 

usando el TimeService lo largo de todo el código y nunca utilizando new Date() es una muy buena práctica y tiene otras ventajas también. Lo encontré útil en varias ocasiones, incluida la prueba funcional manual de funciones que se activarán en el futuro. Yendo más lejos, la hora del sistema puede ser recuperada desde un sistema externo por lo que es consistente a través de grupos etc.

+0

Escribí un artículo más detallado [publicar aquí] (http://larselrund.com/2011/08/05/junit-with-new-date/) para aquellos que deseen leer más sobre el uso el servicio separado para recuperar la fecha actual. – Neovibrant

0

También puede crear un método getDate, y una var estática fecha:

private static Date thisDate = null; 

    @Override 
    public void saveLastSuccesfullLogin(final User user) { 
     gebruiker.setLastLogin(getDate()); 
     storeUser(user); 
    } 

    public Date getDate() { 
     if(thisDate != null) return thisDate; 
     return new Date(); 
    } 

    public void setDate(Date newDate) { 
     thisDate = newDate; 
    } 

Luego, en su método de prueba, puede continuar y llamar a setDate para controlar qué fecha obtendrá.