簡體   English   中英

使用Spock在Java中模擬私有靜態最終變量

[英]Using Spock to mock private static final variables in Java

我正在嘗試用Groovy編寫一些Spock測試來測試一些Java代碼(特別是一個servlet Filter)。 我有一些private staticprivate static final變量,我想模擬,但我無法確定是否有辦法做到這一點。 我知道metaClass可用於方法,變量有什么類似的嗎?

例如,我有:

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

我嘗試使用Mock(MyFilter) ,以及使用Java反射來更改值(基於此問題並使用Java反射更改私有靜態最終字段 )。

我想這樣做而不添加像Mockito或其他框架的東西,如果可能的話,只需使用普通的Groovy和Spock。

謝謝你的任何想法!

更新1

至少對於private static變量我確實得到以下工作:

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

但我仍然無法繞過final方面。

更新2

感謝Xv。 我現在可以用以下內容設置:

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

基於我從https://stackoverflow.com/a/25031713/239408學到的東西,這對我來說很有用

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

看起來你錯過了Modifier.FINAL標志的取消設置。

您需要使用PowerMock(或其他類似的解決方案),或重構您的代碼。 Spock不支持自己模擬私有/靜態/最終方法。 Mockito中也存在此限制,因此必須提供最佳實踐的提示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM