2011-10-12 15 views
11

Tengo algunas pruebas JUnit que usan TemporaryFolder . Utilizan el TemporaryFolder en un método @Before para llevar a cabo algún tipo de configuración:JUnit @Rule interacción del ciclo de vida con @Antes de

@Rule 
public TemporaryFolder folder = new TemporaryFolder(); 

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

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

La mayoría de las veces esto funciona perfectamente. Sin embargo, al utilizar el SpringJUnit4ClassRunner encuentro que en algunos casos se invoca el método init() antes de que se aplique Statement dentro de mi instancia TemporaryFolder. Debido a esto, la ubicación de la carpeta temporal no está configurada (es decir: null) cuando se usa folder dentro de init() y mi archivo termina en el directorio de trabajo, no /tmp.

De modo que en algunos casos los métodos @Before se ejecutan antes que las reglas, sin embargo, no puedo establecer un patrón definido. Ocasionalmente veo un problema similar con algunas de mis propias implementaciones de reglas.

¿Hay alguna manera de asegurarme de que mis declaraciones de reglas se apliquen antes de cualquier método de configuración?

Respuesta

11

En JUnit 4.10, BlockJUnit4ClassRunner (la superclase de SpringJUnit4ClassRunner) parece tener cuidado de construir cadenas de instrucciones de tal manera que las reglas se ejecutan antes que cualquier método @Before. De JUnit 4.10: 4.7 aparece

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 a puntada cadenas Declaración juntos en un orden diferente: POM matriz de

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; 

-pruebas de la primavera-3.0.5 parece indicar que depende de JUnit 4.7. Me pregunto si conseguirlo para usar un JUnit más nuevo ayudaría.

+1

Buen hallazgo @pholser. Estoy usando JUnit 4.8.xy eso parece construir las cadenas en el mismo orden que 4.10. Sin embargo, el método Bloquear() se reemplaza en SpringJUnit4ClassRunner y establece un orden diferente similar al de JUnit 4.7. – teabot

0

Por lo que vale la pena, he utilizado la siguiente como una solución rápida:

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

Esto asegura que el TemporaryFolder se ha inicializado correctamente, independientemente de si los métodos @Before se ejecutan antes o después de las reglas.

Cuestiones relacionadas