2011-10-12 9 views
11

Ho alcuni test JUnit che utilizzano lo TemporaryFolder@Rule. Usano il TemporaryFolder in un metodo @Before per eseguire alcune operazioni di configurazione:Interazione ciclo di vita JUnit @Rule con @Before

@Rule 
public TemporaryFolder folder = new TemporaryFolder(); 

@Before 
public void init() { 
    folder.newFile("my-file.txt"); 
} 

@Test 
public void myTest() { ... } 

Il più delle volte questo funziona perfettamente. Tuttavia, quando si utilizza SpringJUnit4ClassRunner, in alcuni casi viene rilevato il metodo init() prima che venga applicata la Statement all'interno della mia istanza TemporaryFolder. Per questo motivo, la posizione della cartella temporanea non è impostata (ad esempio: null) quando folder viene utilizzato all'interno di init() e il mio file finisce nella directory di lavoro, non /tmp.

Quindi in alcuni casi i metodi @Before vengono eseguiti prima delle regole, tuttavia, non riesco a stabilire uno schema definito. Occasionalmente vedo un problema simile con alcune delle mie implementazioni di regole.

Esiste un modo per garantire che le mie istruzioni di regole vengano applicate prima di qualsiasi metodo di configurazione?

risposta

11

In JUnit 4.10, BlockJUnit4ClassRunner (la superclasse di SpringJUnit4ClassRunner) sembra avere cura di costruire catene di istruzioni in modo tale che le regole vengano eseguite prima dei metodi @Before. Da JUnit 4.10:

protected Statement methodBlock(FrameworkMethod method) { 
    // ... 
    Statement statement= methodInvoker(method, test); 
    statement= possiblyExpectingExceptions(method, test, statement); 
    statement= withPotentialTimeout(method, test, statement); 
    statement= withBefores(method, test, statement); 
    statement= withAfters(method, test, statement); 
    statement= withRules(method, test, statement); 
    return statement; 
} 

JUnit 4.7 sembra cucire catene Dichiarazione insieme in un ordine diverso: POM genitore

Statement statement= methodInvoker(method, test); 
statement= possiblyExpectingExceptions(method, test, statement); 
statement= withPotentialTimeout(method, test, statement); 
statement= withRules(method, test, statement); 
statement= withBefores(method, test, statement); 
statement= withAfters(method, test, statement); 
return statement; 

primavera-test-3.0.5 sembra indicare che dipende da JUnit 4.7. Mi chiedo se ottenerlo per usare un JUnit più recente sarebbe d'aiuto?

+1

Buona ricerca @pholser. Sto usando JUnit 4.8.x e sembra costruire le catene nello stesso ordine di 4.10. Tuttavia, methodBlock() viene sovrascritto in SpringJUnit4ClassRunner e imposta un ordine diverso simile a quello di JUnit 4.7. – teabot

0

Per quello che vale, ho usato il seguente come una soluzione rapida:

@Rule 
public TemporaryFolder tmpFolder = new TemporaryFolder() { 
    @Override 
    protected void before() throws Throwable { 
     if (getRoot() == null) { 
      super.before(); 
     } 
    } 

    @Override 
    public File newFile(String fileName) throws IOException { 
     try { 
      before(); 
     } 
     catch (Throwable t) { 
      throw new RuntimeException(t.getMessage(), t); 
     } 

     return super.newFile(fileName); 
    } 

    @Override 
    public File newFolder(String folderName) { 
     try { 
      before(); 
     } 
     catch (Throwable t) { 
      throw new RuntimeException(t.getMessage(), t); 
     } 

     return super.newFolder(folderName); 
    } 
}; 

Questo assicura che il TemporaryFolder viene inizializzato correttamente, indipendentemente dal fatto che i metodi @Before vengono eseguiti prima o dopo le regole.

Problemi correlati