Java中静态类上的Field.set()
我正在尝试编写一些单元测试,以断言在我的应用程序中,不同版本的Android SDK都使用了适当的密码套件 为了模拟Build.VERSION.SDK_INT的结果,我尝试使用Field.set调用 我有一个实用方法,它看起来像是从链接的答案中提取出来的:Java中静态类上的Field.set(),java,android,reflection,Java,Android,Reflection,我正在尝试编写一些单元测试,以断言在我的应用程序中,不同版本的Android SDK都使用了适当的密码套件 为了模拟Build.VERSION.SDK_INT的结果,我尝试使用Field.set调用 我有一个实用方法,它看起来像是从链接的答案中提取出来的: private static void mockSdkVersion(Field field, Object newValue) throws Exception { field.setAccessible(true); Fi
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我怎样才能模拟这个呢?每次测试方法调用后,您都需要重置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 );
}
我发现我可以通过简单地向测试方法添加@Configsdk=Build.VERSION\u CODES.XXX注释来复制我想要的行为,假设您使用的是RoboElectric
为什么这些话现在进入我的脑海?我知道。。。但是这个代码库非常不稳定。。。努力解决这个问题……此外,我正在调用的是一个静态类,我觉得我会遇到同样的问题,无法模拟PowerMock还不是一个选项……就个人而言,我会试图避免单元测试静态类,因为你显然想摆脱它们。如果可能的话,我会尝试看一看端到端的集成测试,这将为您的重构工作提供更有价值的支持。。。然而,我对集成测试知之甚少,我仍在学习单元测试的who/what/where/when/why/how。。。我们有自上而下的授权和合并检查,包括所有新代码的单元测试。。。而这个故事-为了更新安卓“O”的密码套件-只编辑静态类…不会在所有测试之后运行一次??啊,不,它会在每个测试之后运行。。。但不幸的是,我没有看到变化。