2014-12-18 11 views
6

Sto provando a scrivere alcuni test di Spock con Groovy per testare qualche codice Java (in particolare un filtro servlet). Ho alcune variabili private static e private static final che mi piacerebbe prendere in giro, ma non riesco a determinare se c'è un modo per farlo. So che metaClass è disponibile per i metodi, c'è qualcosa di simile per le variabili?Utilizzo di Spock per deridere le variabili finali statiche private in Java

Per esempio, ho:

public class MyFilter implements Filter { 
    private static WebResource RESOURCE; 
    private static final String CACHE_KEY = "key-to-be-used-for-cache"; 
    ... actual methods, etc ... 
} 

Ho provato con Mock(MyFilter), così come l'utilizzo di Java riflessione per modificare il valore (sulla base di questa domanda e risposta Change private static final field using Java reflection).

Mi piacerebbe farlo senza aggiungere qualcosa come Mockito o altri framework, se possibile, basta usare semplicemente Groovy e Spock.

Grazie per qualsiasi idea!

UPDATE 1

Almeno per private static variabili ho avuto il seguente al lavoro:

Field field = MyFilter.class.getDeclaredField("CACHE_KEY") 
field.setAccessible(true) 
field.set(null, "new-key-value") 

Ma ancora non sono stato in grado di aggirare l'aspetto final.

UPDATE 2

Grazie a XV. Ora posso impostare questo con il seguente:

Field field = MyFilter.class.getDeclaredField("CACHE_KEY") 
field.setAccessible(true) 

Field modifiersField = Field.class.getDeclaredField("modifiers") 
modifiersField.setAccessible(true); 
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 

field.set(null, "new-key-value") 
+0

Suppongo che dipenda da come viene testato, ma IMO utilizzando un framework progettato per fare ciò che stai cercando di fare è l'approccio migliore e più ampiamente applicabile, ad esempio http://java.dzone.com/ articoli/mocking-static-methods-groovy e http://stackoverflow.com/a/15834010/438992 ecc. –

+0

Grazie per il tuo commento @DaveNewton - in particolare con Peter Niederwieser che afferma che solo i metodi definiti groovy possono essere derisi in Spock. Il mio caso è specifico per campi/variabili di classe, ma controllerò per vedere se uno degli altri framework sarebbe in grado di farlo per me. Grazie. – mnd

+2

So che non è quello che stai cercando, ma qualche tempo fa ho giocato con la combinazione di [Spock e PowerMock] (https://github.com/kriegaex/Spock_PowerMock) per simulare metodi statici. Non ricordo se funziona anche per membri finali (statici), prova solo per te stesso. Ma quello che in realtà voglio dire è che se il tuo codice è così difficile da testare, non dovresti aggiornare i test o gli strumenti di test ma rifatti il ​​codice per verificabilità. Penso che ogni volta che hai bisogno di trucchi come quelli che vuoi o strumenti per darti quello che vuoi, questo è un ** odore di codice **. – kriegaex

risposta

5

Sulla base di quello che ho imparato da https://stackoverflow.com/a/25031713/239408, questo funziona per me Spock

import java.lang.reflect.Field 
import java.lang.reflect.Modifier 

... 

    def setup() { 

     Field field = BackendCredentials.getDeclaredField("logger") 
     field.setAccessible(true); 

     Field modifiersField = Field.class.getDeclaredField("modifiers"); 
     modifiersField.setAccessible(true); 
     modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 

     field.set(null, Mock(Logger)) 
    } 

Sembra che vi manca il disinserimento della bandiera Modifier.FINAL.

1

O è necessario utilizzare PowerMock (o un'altra soluzione simile), o il refactoring del codice. Spock non supporta il mocking dei metodi privati ​​/ statici/finali da solo. Questa limitazione è presente anche in Mockito, quindi è necessario fornire un suggerimento sulle migliori pratiche.

Problemi correlati