JUnit @Rule Lifecycle interaction avec @Before

J’ai des tests JUnit qui utilisent le @Rule TemporaryFolder @Rule . Ils utilisent le TemporaryFolder dans une méthode @Before pour effectuer certaines configurations:

 @Rule public TemporaryFolder folder = new TemporaryFolder(); @Before public void init() { folder.newFile("my-file.txt"); } @Test public void myTest() { ... } 

La plupart du temps, cela fonctionne parfaitement. Cependant, lors de l’utilisation de SpringJUnit4ClassRunner je constate que dans certains cas, la méthode init() est invoquée avant que l’ Statement dans mon instance TemporaryFolder soit appliquée. Pour cette raison, l’emplacement du dossier temporaire n’est pas défini (c’est-à-dire: null ) lorsque le folder est utilisé dans init() et que mon fichier se termine dans le répertoire de travail, pas /tmp .

Ainsi, dans certains cas, les méthodes @Before sont exécutées avant les règles, mais je ne peux pas établir de modèle précis. Je vois parfois un problème similaire avec certaines de mes propres implémentations de règles.

Est-il possible de m’assurer que mes instructions de règle sont appliquées avant les méthodes d’installation?

Dans JUnit 4.10, BlockJUnit4ClassRunner (la super-classe de SpringJUnit4ClassRunner) semble prendre soin de construire des chaînes d’instructions de manière à ce que les règles soient exécutées avant les méthodes @Before. À partir de 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 semble assembler des chaînes d’instructions dans un ordre différent:

 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; 

Le POM parent de spring-test-3.0.5 semble indiquer qu’il dépend de JUnit 4.7. Je me demande si le fait d’utiliser un nouveau JUnit pourrait vous aider?

Pour ce que cela vaut, j’ai utilisé la solution suivante comme solution de contournement rapide:

 @Rule public TemporaryFolder tmpFolder = new TemporaryFolder() { @Override protected void before() throws Throwable { if (getRoot() == null) { super.before(); } } @Override public File newFile(Ssortingng fileName) throws IOException { try { before(); } catch (Throwable t) { throw new RuntimeException(t.getMessage(), t); } return super.newFile(fileName); } @Override public File newFolder(Ssortingng folderName) { try { before(); } catch (Throwable t) { throw new RuntimeException(t.getMessage(), t); } return super.newFolder(folderName); } }; 

Cela garantit que le @Before TemporaryFolder est correctement initialisé, que les méthodes @Before soient exécutées avant ou après les règles.