Cutre maquina del tiempo

07-08-2008

Una de las pruebas típicas de un programador la de verificar el funcionamiento del sistema con las fechas. (No, y no me refiero sólo a las que hacían con lo del año 2000). Y es un poco rollo porque tienes que cambiar la fecha de todo el sistema. En algunos sistemas y aplicaciones con las que he trabajado, se definía una rutina común que gestionaba las fechas, y para hacer pruebas se podía parchear.

En el mundo Java no es tan fácil, porque lo habitual es tomar la fecha del sistema. Y la fecha de la máquina virtual se toma de la fecha de la máquina donde se ejecuta. Así que me vi en el caso de tener que hacer pruebas cambiando la fecha del sistema...

Vi por Internet ideas peregrinas, y como a mi me encantan las ideas retorcidas, pues me puse a aplicarla. Aporté mi granito de arena a la idea original: cambiar la fecha del sistema desde un test de JUnit, y restaurar a la fecha original cuando la prueba termina.

Creo la clase de prueba extendiendo junit.framework.TestCase.

En el método setUp() almaceno la fecha y hora del sistema (para poder restaurarla). Los formatos de las cadenas son los que se utilizan en el "cmd.exe" del Windows XP Español (sospecho que el formato es diferente en las versiones de lengua inglesa). Este método se ejecuta antes de los tests, así que es el lugar adecuado para guardar el estado inicial de los datos.

protected void setUp() throws Exception {
		// guardar la fecha del sistema para restaurarla al final del test
		Calendar calendar = GregorianCalendar.getInstance();
		SimpleDateFormat dateFormatter = new SimpleDateFormat("dd/MM/yyyy");
		originalDate = dateFormatter.format(calendar.getTime());
		SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm");
		originalTime = timeFormatter.format(calendar.getTime());
		
	}

Y en el método tearDown() recupero los valores que se habían guardado antes de comenzar los tests. El método tearDown() se ejecuta al finalizar todos los tests. (Y por lo que he visto en mis pruebas se ejecuta siempre: incluso aunque durante el test aparezca alguna RuntimeException).

	protected void tearDown() throws Exception {
		// restauramos la fecha del sistema que se había guardado al principio
		Runtime.getRuntime().exec("cmd /c DATE "+ originalDate);
		Runtime.getRuntime().exec("cmd /c TIME " + originalTime);
	}

Vale, hasta el momento no hemos hecho nada (bueno, ya tenemos la "red" que devuelve al sistema a la fecha original si algo va mal, que no es poco). Para cambiar la fecha, dentro de cada test se ejecuta el siguiente código:

	public void testGetDueDate() 
	{

		// Cambia la fecha del sistema, parandose 1000 milis
		// para que el JVM se sincronice con la fecha del sistema
		try {
			Runtime.getRuntime().exec("cmd /c DATE 08/08/2008");
			Runtime.getRuntime().exec("cmd /c TIME 08:08");
			Thread.sleep(1000);
		} catch (Exception e) {
			return;
		}
		// aquí va el código de la prueba
		(...)
	}	

Pues nada del otro mundo como podeis ver. Es sencillamente el cambiar la fecha del sistema llamando a las utilidades que vienen dentro del "cmd.exe" del Windows, con cadenas de texto a lo bruto. Lo único que require un poco de comentario es el Thread.sleep(1000). Si cambias la fecha del sistema y ejecutas inmediatamente despues un new Date(), te llevarás la pequeña sorpresa de que aún tiene la fecha antigua. La razón de esto (y lo descubrí en la práctica) es que Java no lee la hora del sistema coninuamente, si no que la va revisando de tiempo en tiempo. Así que tarda unos cuantos milisegundos en darse cuenta del cambio de tiempo. (Yo he puesto 1 segundo de espera, y seguramente me he pasado un rato, pero me sobra tiempo en el test así que no me he esforzado a ajustar esto mucho).

¡Ah! Si, sólo he puesto como se hace en Windows. Porque era lo que me hacía falta. Esto mismo se puede hacer en Mac OS X, Linux y cualquier cosa que acabe en *X. Pero como sois tan buenos, no os costará nada encontrar el comando equivalente (tambien se llama "date").


feed de comentarios - top


·La Rabadilla· ·Laconada· ·iRamos· ·O Vello Corvo· ·Palabros·
counter [CSS 2 Valid!] [XHTML 1.0 Valid!] [Made with Ant] [Get Firefox] RSS 1.0RSS 1.0 Atom 1.0RSS 1.0