在每个单元测试开始时重新加载静态变量

iam*_*nak 5 java junit android classloader robolectric

我正在使用大量静态方法对 SDK 进行单元测试。而且我不希望我在 test1() 中所做的操作影响我在 test2() 中所做的操作。在每次测试开始时,我需要 SDK 中的所有静态变量返回到未初始化状态,就好像它们没有加载一样。然后再次加载它们。关于如何做到这一点的任何建议?Robolectric 中是否有类似的规定?因为我用它来进行单元测试。在计划英语中,我基本上想要的是在每次测试开始时都有一个干净的石板。

@Test
public void test1() throws Exception {
    // Setup all the device info values
    MyDeviceInfoClass.setDeviceModel().equals("Nexus 4");
    MyDeviceInfoClass.setDeviceOperatingSystem().equals("Android_3.4b5");

    // Verify all the device info values set previously
    assertTrue(MyDeviceInfoClass.getDeviceModel().equals("Nexus 4"));
    assertTrue(MyDeviceInfoClass.getDeviceOperatingSystem().equals("Android_3.4b5"));
}
Run Code Online (Sandbox Code Playgroud)

那是第一次测试,它成功了。就是它应该的样子。然后在第二个测试中:

@Test
public void test2() throws Exception {
      // Setup all the device info values
      MyDeviceInfoClass.setDeviceOperatingSystem().equals("Android_4.2");

      //The following line also succeeds if test1() is finished. But I do not want that. This line should throw an assertion error because we did not specify what the device is over here in test2().
      assertTrue(MyDeviceInfoClass.getDeviceModel().equals("Nexus 4"));
      //This will succeed just the way it should be.
      assertTrue(MyDeviceInfoClass.getDeviceOperatingSystem().equals("Android_4.2"));
}
Run Code Online (Sandbox Code Playgroud)

我不希望第一个测试中设置的值对第二个测试中获取的值产生影响。上面显示的测试是简单的示例。但是我正在进行单元测试的 SDK 比这更复杂。

更清楚地说,我不希望在 test1() 中设置的值对 test2() 中正在执行的操作产生任何影响。如果我像这样 MyDeviceInfoClass.setDeviceModel().equals("Nexus 4") 在 test1() 中将设备模型设置为 Nexus 4,那么当我通过 MyDeviceInfoClass.setDeviceModel 获取它时,第二个测试 test2() 不必知道它().equals("Nexus 4")。我希望在我的单元测试之间完全隔离。

远离静态方法也不是一种选择。请告诉我如何实现这一目标。

编辑: 由于项目中涉及某些复杂性,因此在测试开始之前重置所有静态变量也不是一种选择。

Bri*_*ach 3

卸载静态变量的唯一时间是当加载相关类的类加载器被垃圾收集时。

解决问题的一种方法是使用您自己的类加载器。这里有一个很好的问题,它相当广泛地详细介绍了这一点。

另一种选择是在每次测试之前简单地重置值。您可以@Before在测试类中提供一个带注释的方法来重置它们,如有必要,可以使用反射。