2010-05-11 5 views
9

J'ai une classe de surveillance de fichiers très simple qui vérifie toutes les 2 secondes si un fichier a changé et si oui, la méthode onChange (void) est appelée. Existe-t-il un moyen facile de vérifier si la méthode onChange est appelée dans un test unitaire?JUnit: vérifier si une méthode void est appelée

code:

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"); 
    } 
} 

Test:

@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(); 
} 

Répondre

16

Avec Mockito, vous pouvez vérifier si une méthode est appelée au moins une fois/jamais.

Voir point 4 this page

par exemple:

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

Vous pouvez utiliser n'importe quel cadre de simulation et pas seulement mockito. Jetez un oeil à EasyMock ou jMock et choisissez ce que vous aimez. La règle de base de l'écriture des tests unitaires est que vous ne devez que simuler les objets que vous pouvez contrôler. En d'autres termes, les objets fantaisie doivent être mis à la disposition de la classe testée en utilisant des arguments constructeurs ou des paramètres de votre méthode testée. Par cette logique, vous ne pouvez pas vous moquer des invocations statiques, finales ou privées, ou des «nouveaux» objets créés à l'intérieur de la méthode de la classe testée. – Kartik

+0

Une idée de comment vous pouvez le faire dans EasyMock? Je trouve que la documentation manque à ce sujet. Lorsque je crée un simulacre pour PropertyFileWatcher comme ceci: PropertyFileWatcher propertyFileWatcher = createMockBuilder (PropertyFileWatcher.class) .withConstructor (fichier) .createMock(); et enregistrer l'appel attendu à onChange et rejouer: propertyFileWatcher.onChange (file); replay (propertyFileWatcher); la méthode onChnage est appelée immédiatement et info est imprimée à sysout, mais je voudrais juste vérifier si cette méthode a été appelée ou non – nkr1pt

+0

Ne pas utiliser mockito étant capable de faire la solution AtomicBoolean. –

4

Si je comprends bien, votre PropertyFileWatcher est destiné à être sous-classé. Alors, pourquoi ne pas le sous-classer comme ceci:

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

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

Voici une simple modification pour votre test.

@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

J'aime vraiment cette solution parce qu'elle n'ajoute pas de dépendance à un cadre moqueur; cependant, les cadres moqueurs sont une nécessité pour les tests unitaires; C'est pourquoi j'accepte la suggestion moqueuse comme la réponse acceptée à ma question. – nkr1pt

+0

@ nkr1pt. Certainement aller avec un cadre moqueur réputé. Si vous n'êtes pas limité à la version 1.4 de JDK, jetez un oeil à jMock. –

Questions connexes