java - Java 中静态类的 Field.set()

标签 java android reflection

我正在尝试编写一些单元测试来断言我的应用程序中不同版本的 Android SDK 使用了正确的密码套件。

为了模拟 Build.VERSION.SDK_INT 的结果,我尝试使用 Field.set() 调用...

我有一个如下所示的实用方法(从 https://stackoverflow.com/a/40303593/1226095 和链接的答案中提取):

private static void mockSdkVersion(Field field, Object newValue) throws Exception {
    field.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, newValue);
}

然后我有几个使用它的测试,如下所示:

 @Test
    public void testApprovedCipherListForApi16() throws Exception {
        // force SDK_INT to 16
        mockSdkVersion(Build.VERSION.class.getField("SDK_INT"), 16);
        // obtain the list of suites that should be returned for API 16
        ArrayList<String> approvedCipherSuites = ConnectionSpec.APPROVED_CIPHER_SUITES;
        // assert things...
    }

@Test
public void testApprovedCipherListForApi20() throws Exception {
    // force SDK_INT to 20
    mockSdkVersion(Build.VERSION.class.getField("SDK_INT"), 20);
    // obtain the list of suites that should be returned for API 20
    ArrayList<String> approvedCipherSuites = ConnectionSpec.APPROVED_CIPHER_SUITES;
    // assert things...
}

当我一次运行一个测试时,这是有效的,但是当我一次运行所有测试时(例如使用像 Jenkins 这样的 CI 设置),它似乎不会重置该值(它保持在 16),假设是因为它是静态的。

有什么想法吗 a) 我怎样才能解决这个问题? b)我如何可以替代地 mock 这个?

最佳答案

每次测试方法调用后,您需要重置 Build.VERSION。像这样的事情:

private static final int DEFAULT_VERION = Build.VERSION.SDK_INT;

@After
public void after(){
    mockSdkVersion( Build.VERSION.class.getField("SDK_INT"), DEFAULT_VERION );
}

关于java - Java 中静态类的 Field.set(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45021731/

相关文章:

android - achartengine - 不同点和线的不同颜色

Android 虚拟设备方向(这是不同的)

java - import org.opencv.imgcodecs.Imgcodecs无法解析

java - 通过Maven依赖导入hikaricp后出现NoClassDefFoundError

java - 在java中寻找ElGamal算法子群的生成器?

c# - Type.GUID 是否跨编译唯一标识每种类型?

c# - 如何使用反射递归打印对象属性的值

java - 调用时不会显示字符串

java - 单击按钮时 TextView 不会更新

c# - 使用 Intellisense 和编译时检查提取属性名称以进行反射