2011-10-12 10 views
11

Mam kilka testów JUnit, które używają TemporaryFolder@Rule. Używają TemporaryFolder w metodzie @Before wykonać pewne Setup:Interakcja JUnit @Rule lifecycle z @Before

@Rule 
public TemporaryFolder folder = new TemporaryFolder(); 

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

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

Większość czasu to działa doskonale. Jednak przy korzystaniu z SpringJUnit4ClassRunner stwierdzam, że w niektórych przypadkach metoda init() jest wywoływana przed zastosowaniem instancji Statement wewnątrz mojej instancji . Z tego powodu lokalizacja folderu tymczasowego jest rozbrajana (tj .: null), gdy folder jest używana w obrębie init(), a mój plik kończy się w katalogu roboczym, a nie /tmp.

W niektórych przypadkach metody są wykonywane przed regułami, jednak nie mogę ustalić określonego wzorca. Czasami widzę podobny problem z niektórymi z moich własnych implementacji reguł.

Czy jest jakiś sposób, aby upewnić się, że moje reguły zostały zastosowane przed metodami konfiguracji?

Odpowiedz

11

W JUnit 4.10, BlockJUnit4ClassRunner (nadklasa SpringJUnit4ClassRunner) wydaje się uważać, aby skonstruować łańcuchy instrukcji w taki sposób, aby reguły były uruchamiane przed metodami @Before. Od JUnit 4.10: 4.7 pojawia

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 do ściegu łańcuchy komunikat razem w innej kolejności: rodzic POM

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; 

wiosna-test-3.0.5 wydaje się wskazywać, że to zależy od JUnit 4.7. Zastanawiam się, czy pomoc w korzystaniu z nowszej JUnit pomogłaby?

+1

Dobre rozwiązanie @pholser. Używam JUnit 4.8.x i wygląda na to, że konstruuje łańcuchy w tej samej kolejności, co 4.10. Jednak metoda Block() jest nadpisana w SpringJUnit4ClassRunner i ustawia inną kolejność podobną do JUnit 4.7. – teabot

0

Na co warto, Użyłem następujących postaci szybkiego obejścia:

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

Gwarantuje to, że TemporaryFolder jest inicjowana prawidłowo, niezależnie od tego, czy metody @Before są prowadzone przed lub po zasad.