5

我正在对具有大量静态方法的 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"));
}

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

@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"));
}

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

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

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

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

4

1 回答 1

3

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

解决问题的一种方法是使用您自己的类加载器。这里有一个很棒的 SO question ,其中涵盖了相当广泛的细节。

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

于 2013-07-05T21:12:07.703 回答