运行 JUnit 测试时不执行静态类初始化



我有一个带有一些静态字段的java类:

private static final PDMapCacheDAO REST_CACHE_DAO = 
    new PDMapCacheDAOImpl( Constants.REST_CACHE_NAME );
private static final PDMapCacheDAO HOLIDAYS_CACHE_DAO = 
    new PDMapCacheDAOImpl( Constants.HOLIDAYS_CACHE_NAME );
private static final String[] DATE_ARRAY = { "D", "0", "1", "2", "3", "C" };

JUnit 测试模拟了REST_CACHE_DAO和HOLIDAYS_CACHE_DAO的初始化行为:

final PDMapCacheDAOImpl holidaysMapCacheDAOImpl = mock(PDMapCacheDAOImpl.class);
final PDMapCacheDAOImpl restMapCacheDAOImpl = mock(PDMapCacheDAOImpl.class);
whenNew(PDMapCacheDAOImpl.class).withArguments(Constants.HOLIDAYS_CACHE_NAME).thenReturn(holidaysMapCacheDAOImpl);
whenNew(PDMapCacheDAOImpl.class).withArguments(Constants.REST_CACHE_NAME).thenReturn(restMapCacheDAOImpl);
单独执行测试时,测试按

预期执行,但是当所有 JUnit 测试一起执行时(从具有运行方式 --> Junit Test 的 Java 项目中),测试会给出空指针异常。

我已经做了一些调试,我发现问题(如标题中所述)是静态类未初始化 - 当调用静态方法时,REST_CACHE_DAO和HOLIDAYS_CACHE_DAO为空。PDMapCacheDAOImpl的构造函数没有被调用,模拟也没有被注入,因此当我们使用它们时,它会给出一个NPE。

我已经阅读了一些执行测试的工具,例如具有此错误的eclemma(某些静态类未初始化)。在这种情况下,解决方案是包含 -f 选项。

这就是Eclemma网站对这个问题的看法:"

2.8. EMMA如何定义类别覆盖率? 首先,一个类需要被认为是可执行的,甚至可以考虑覆盖。如果可执行类已由 JVM 加载和初始化,则认为该类已被覆盖。类初始化意味着执行类静态构造函数(如果有)。请注意,即使尚未执行其他方法,也可以覆盖该类。当您使用 emmarun 而不使用 -f 选项时,通常会看到少量已加载但未初始化的类。 EMMA 报告类覆盖率,以便您可以发现似乎没有被测试套件"触及"的类:它们可能是死代码或需要更多测试关注。

有趣的是,我们不是在使用Eclemma,而是在使用Cobertura,但是行为和错误是相同的。

有谁知道Cobertura中的此错误以及如何解决它?(无论是在科伯图拉还是以通用方式)?

这是推测性的。

我想PDMapCacheDAO是一个接口/抽象类,它对某些常量使用 PDMapCacheDAOImpl

PDMapCacheDAOImpl 实现/扩展PDMapCacheDAO.右?

由于我发现这是一个技术上丑陋的解决方案(互惠依赖),因此请使用这些常量PDMapCacheDAOs单独的接口。

这也许可以解决问题。

最后,我们决定改用 Singleton,并避免静态初始化的所有问题。我不得不对公司说,问题仍然存在,将来可能会再次发生,但我迫不及待地想让 SQA 团队解决它。

感谢您的所有回复和时间

最新更新