2014-12-18 14 views
6

Bazı Java kodlarını (özellikle bir Servlet Filtresi) test etmek için Groovy ile bazı Spock testleri yazmaya çalışıyorum. Ben alay etmek istediğim bazı private static ve private static final değişkenler var, ancak bunu yapmanın bir yolu olup olmadığını belirleyemiyorum. Ben metaClass yöntemleri için kullanılabilir biliyorum, değişkenler için benzer bir şey var mı?Özel statik son değişkenleri Java'ya eşleştirmek için Spock'i ​​kullanma

Mesela ben vardır:

Ben Mock(MyFilter) kullanarak, hem de değerini değiştirmek için Java yansıma kullanarak denedim
public class MyFilter implements Filter { 
    private static WebResource RESOURCE; 
    private static final String CACHE_KEY = "key-to-be-used-for-cache"; 
    ... actual methods, etc ... 
} 

(Bu soruya dayanarak ve Change private static final field using Java reflection cevap).

Mockito veya diğer çerçeveler gibi bir şey eklemeden bunu yapmak isterim, eğer mümkünse, sadece Groovy ve Spock kullanın.

Herhangi bir fikir için teşekkürler!

GÜNCELLEME

1 En az private static değişkenler için ben aldım çalışmak için aşağıdaki:

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

Ama yine final yönüyle kurtulmak mümkün olmamıştır.

GÜNCELLEME Xv için 2

teşekkür ederiz.

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

Sanırım nasıl test edildiğine bağlı, ancak yapmaya çalıştığınız şeyi yapmak için tasarlanan bir çerçeve kullanan IMO daha iyi bir yaklaşım ve daha geniş bir şekilde uygulanabilir, örneğin, http://java.dzone.com/ Makaleler/alay-statik-yöntemler-groovy ve http://stackoverflow.com/a/15834010/438992 vb –

+0

Yorumunuz için teşekkürler @DaveNewton - özellikle Peter Niederwieser ile Spock sadece yüce tanımlı yöntemler alay edilebilecek belirten. Davam sınıfsal alanlara/değişkenlere özgüdür, ancak diğer çerçevelerden birinin bunu benim için yapıp yapamayacağını kontrol edeceğim. Teşekkürler. – mnd

+2

Aradığınızı değil biliyorum, ama bir süre önce [Spock ve PowerMock] (https://github.com/kriegaex/Spock_PowerMock) ile statik yöntemlerle alay etmek için oynadım. Ayrıca (nihai) statik üyeler için çalışıp çalışmadığını hatırlamıyorum, sadece kendiniz deneyin. Ancak aslında söylemek istediğim, kodunuzun test edilmesi çok zorsa, testlerinizi veya test araçlarınızı yükseltmemeli, ancak kodun test edilebilirliğini yeniden düzenlemelisiniz. Ne istersen ya da istediğini vermek için araçlar gibi hileler ihtiyacınız olduğunda, bu bir ** kod kokusu ** olduğunu düşünüyorum. – kriegaex

cevap

5

ben https://stackoverflow.com/a/25031713/239408 öğrenilen dayanarak, bu Modifier.FINAL bayrağın unsetting eksik gibi

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

görünüyor spock içinde benim için çalışıyor.

1

Ya PowerMock (veya başka benzer bir çözüm) kullanmak gerekir, veya kodunuzu: Şimdi şu bu ayarlayabilirsiniz. Spock, özel/statik/son yöntemlerin kendi başına alay edilmesini desteklemez. Bu sınırlama, Mockito'da da mevcuttur, bu yüzden size en iyi uygulamalar hakkında bir ipucu vermek zorundadır.

İlgili konular