2013-10-28 4 views
16

Sto usando PowerMock per deridere i metodi statici in test JUnit, in genere fatto come segue:Sostituzione di PowerMock @PrepareForTest a livello di programmazione?

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Foo.class,Bar.class}) 
public class SomeUnitTest { 

    @Before 
    public void setUpTest() { 
    setUpFoo(); 
    setUpBar(); 
    } 

    private void setUpFoo() { 
    mockStatic(Foo.class); 
    when(Foo.someStaticMethod()).thenReturn(1); 
    } 

    private void setUpBar() { 
    mockStatic(Bar.class); 
    when(Bar.someStaticMethod()).thenReturn(2); 
    } 

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

} 

Questo funziona bene, ma ho constatato che specifica l'annotazione è @PrepareForTest mi impedisce di fare il mio test API flessibile.

Quello che mi piacerebbe fare è qualcosa di simile al seguente:

public class MockLibraryOne { 

    public static void setUpLibraryOne() { 
    setUpFoo(); 
    setUpBar(); 
    } 

    private static void setUpFoo() { 
    mockStatic(Foo.class); 
    when(Foo.someStaticMethod()).thenReturn(1); 
    } 

    private static void setUpBar() { 
    mockStatic(Bar.class); 
    when(Bar.someStaticMethod()).thenReturn(2); 
    } 

} 

@RunWith(PowerMockRunner.class) 
public class SomeUnitTest { 

    @Before 
    public void setUpTest() { 
    MockLibraryOne.setUpLibraryOne(); 
    } 

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

} 

Qui il mio test di unità ha una dipendenza LibraryOne, ma non sa quali classi LibraryOne dipende, in modo da non sapere quali classi aggiungere all'annotazione @PrepareForTest.

ho potuto fare SomeUnitTest estendono MockLibraryOne e aggiungere il @PrepareForTest annotazioni alla classe MockLibraryOne, ma avrò dipendenze da più di un semplice MockLibraryOne in altri test di unità, in modo da eredità non è una soluzione generale.

Esiste un modo per preparare a livello di codice una classe per il test con PowerMock, invece di utilizzare l'annotazione @PrepareForTest? Ad esempio, qualcosa come il seguente:

public class MockLibraryOne { 

    public static void setUpLibraryOne() { 
    setUpFoo(); 
    setUpBar(); 
    } 

    private static void setUpFoo() { 
    prepareForTest(Foo.class); 
    mockStatic(Foo.class); 
    when(Foo.someStaticMethod()).thenReturn(1); 
    } 

    private static void setUpBar() { 
    prepareForTest(Bar.class); 
    mockStatic(Bar.class); 
    when(Bar.someStaticMethod()).thenReturn(2); 
    } 

} 

Credo che sarebbe bello se PowerMockRunner elaborato l'@PrepareForTest un'annotazione un po 'diverso: per ogni classe specificata, non dovrebbe aggiungere solo quella classe (e della sua gerarchia) al elenco delle classi per preparare beffardo, ma poi esaminare quella classe per vedere se ci sono delle annotazioni @PrepareForTest così:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({MockLibraryOne.class}) 
public class SomeUnitTest { 
    ... 
} 

@PrepareForTest({Foo.class,Bar.class}) 
public class MockLibraryOne { 
    ... 
} 

}

quindi, in questo il @PrepareForTest annotatio n su SomeUnitTest potrebbe trovare MockLibraryOne e l'annotazione @PrepareForTest potrebbe trascinare in Foo.class e Bar.class pure.

Quindi, forse, scrivere il mio test runner per sostituire PowerMockRunner potrebbe essere una soluzione.

O forse c'è una soluzione più semplice, usando la classe PowerMockAgent, ad esempio?

edit: Politiche Mock possono essere una soluzione: https://code.google.com/p/powermock/wiki/MockPolicies

edit: Politiche Mock funziona con PowerMockRunner ma non (sembra) con PowerMockRule (che a volte ho bisogno a causa di problemi class loader).

+0

Sto affrontando lo stesso problema. Hai trovato qualche soluzione? – Madhujith

+0

Sapete che è possibile utilizzare l'annotazione @PrepareForTest per metodo anziché per classe? – spekdrum

risposta

0

Forse stai cercando uno mock policy?

+0

Grazie per la risposta. Ho studiato 'MockPolicy', ma come ho notato sopra funziona solo con' PowerMockRunner' e non con 'PowerMockRule'. Ho bisogno di usare 'PowerMockRule' a causa dei problemi del programma di caricamento classi e l'inizializzatore' MockPolicy' funziona solo con 'MockClassLoader' fornito da' PowerMockRunner'. –

1

Perché vuoi persino prendere in giro metodi statici? Perché non avvolgere quei metodi statici in una classe che puoi deridere con mockito?

class FooWraper { 
    void someMethod() { 
    Foo.someStaticMethod() 
    } 
} 

e quindi è possibile creare un modello del vostro FooWraper. Non c'è bisogno di usare Powermock ...