2010-05-11 28 views
9

Tengo una clase de observador de archivos muy simple que comprueba cada 2 segundos si un archivo ha cambiado y si es así, se llama al método onChange (void). ¿Existe alguna manera fácil de verificar si se llama al método onChange en una prueba unitaria?JUnit: comprobando si se llama un método nulo

código:

public class PropertyFileWatcher extends TimerTask { 
    private long timeStamp; 
    private File file; 

    public PropertyFileWatcher(File file) { 
     this.file = file; 
     this.timeStamp = file.lastModified(); 
    } 

    public final void run() { 
     long timeStamp = file.lastModified(); 

     if (this.timeStamp != timeStamp) { 
      this.timeStamp = timeStamp; 
      onChange(file); 
     } 
    } 

    protected void onChange(File file) { 
     System.out.println("Property file has changed"); 
    } 
} 

prueba:

@Test 
public void testPropertyFileWatcher() throws Exception { 
    File file = new File("testfile"); 
    file.createNewFile(); 
    PropertyFileWatcher propertyFileWatcher = new PropertyFileWatcher(file); 

    Timer timer = new Timer(); 
    timer.schedule(propertyFileWatcher, 2000); 

    FileWriter fw = new FileWriter(file); 
    fw.write("blah"); 
    fw.close(); 

    Thread.sleep(8000); 
    // check if propertyFileWatcher.onChange was called 

    file.delete(); 
} 

Respuesta

16

Con Mockito, puede comprobar si el método se llama al menos una vez/nunca más.

Véase el punto 4 en this page

por ejemplo:

verify(mockedObject, times(1)).onChange(); // times(1) is the default and can be omitted 
+0

Puede utilizar cualquier marco de burla y no solo mockito. Eche un vistazo a EasyMock o jMock y elija lo que desee. La regla práctica de escribir pruebas unitarias es que solo debe burlarse de los objetos que puede controlar. En otras palabras, los objetos simulados deben estar disponibles para la clase en prueba usando argumentos/parámetros del constructor o parámetros para su método bajo prueba. Según esta lógica, no puede simular invocaciones estáticas, objetos finales o privados o "nuevos" creados dentro del método de la clase bajo prueba. – Kartik

+0

¿Alguna idea de cómo puedes hacerlo en EasyMock? Encuentro que la documentación falta en esto. Cuando creo un simulacro para PropertyFileWatcher de esta manera: PropertyFileWatcher propertyFileWatcher = createMockBuilder (PropertyFileWatcher.class) .withConstructor (file) .createMock(); y grabar la llamada esperada en onChange y reproducir: propertyFileWatcher.onChange (archivo); reproducir (propertyFileWatcher); el método onChnage se llama de inmediato y la información se imprime en sysout, pero solo me gustaría verificar si se llamó o no ese método – nkr1pt

+0

No utilice mockito para poder hacer la solución AtomicBoolean. –

4

Según tengo entendido, su PropertyFileWatcher está destinado a ser una subclase. Entonces, ¿por qué no crear una subclase de esta manera:

class TestPropertyFileWatcher extends PropertyFileWatcher 
{ 
    boolean called = false; 
    protected void onChange(File file) { 
     called = true; 
    } 
} 

... 
TestPropertyFileWatcher watcher = new TestPropertyFileWatcher 
... 
assertTrue(watcher.called); 
7

Aquí hay una modificación simple para su prueba.

@Test 
public void testPropertyFileWatcher() throws Exception { 
    final File file = new File("testfile"); 
    file.createNewFile(); 

    final AtomicBoolean hasCalled = new AtomicBoolean(); 
    PropertyFileWatcher propertyFileWatcher = 
     new PropertyFileWatcher(file) 
     { 
     protected void onChange (final File localFile) 
     { 
      hasCalled.set(true); 
      assertEquals(file, localFile); 
     } 
     } 


    Timer timer = new Timer(); 
    timer.schedule(propertyFileWatcher, 2000); 

    FileWriter fw = new FileWriter(file); 
    fw.write("blah"); 
    fw.close(); 

    Thread.sleep(8000); 
    // check if propertyFileWatcher.onChange was called 

    assertTrue(hasCalled.get()); 
    file.delete(); 
} 
+0

Me gusta mucho esta solución porque no agrega una dependencia a un marco de burla; sin embargo, los marcos burlones son una necesidad para las pruebas unitarias; por eso estoy aceptando la sugerencia burlona como la respuesta aceptada a mi pregunta. – nkr1pt

+0

@ nkr1pt. Definitivamente ve con un marco de burla de buena reputación. Si no está limitado a la versión 1.4 de JDK, eche un vistazo a jMock. –

Cuestiones relacionadas