我有一个带有一些静态字段的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测试一起执行时(从带有Run As的Java项目 - > Junit测试),测试会给出空指针异常。
我做了一些调试,我发现问题(如标题中所述)是静态类未初始化 - 当调用静态方法时,REST_CACHE_DAO和HOLIDAYS_CACHE_DAO为空。不调用PDMapCacheDAOImpl的构造函数并且不注入模拟,因此当我们使用它们时,它会给出一个NPE。
我已经阅读了一些执行测试的工具,比如eclemma有这个错误(某些静态类没有初始化)。在这种情况下,解决方案是包含-f选项。
这是Eclemma网站关于这个问题的说法:“
2.8。 EMMA如何定义班级覆盖范围? 首先,一个类需要被认为是可执行的,甚至可以考虑覆盖。如果已由JVM加载并初始化,则认为可执行类已被覆盖。类初始化意味着执行类静态构造函数(如果有)。请注意,即使没有执行其他方法,也可以覆盖类。在没有-f选项的情况下使用emmarun时,通常会看到少量已加载但未初始化的类。 EMMA会报告课程覆盖范围,以便您可以发现您的测试套件似乎没有“触及”的课程:它们可能是死代码,也可能需要更多测试注意。
有趣的是,我们没有使用Eclemma,我们正在使用Cobertura,但行为和错误是相同的。
有没有人知道Cobertura中的这个错误以及如何解决它? (在Cobertura或通用方式)?
答案 0 :(得分:0)
这是推测性的。
我猜PDMapCacheDAO
是一个接口/抽象类,它使用PDMapCacheDAOImpl
来表示某些常量。
类PDMapCacheDAOImpl
实现/扩展PDMapCacheDAO
。正确?
当我发现这是一个技术上难看的解决方案(reciproke依赖项)时,请使用这些常量创建一个单独的接口PDMapCacheDAOs
。
这可能会解决问题。
答案 1 :(得分:0)
最后我们决定使用Singleton,避免静态初始化的所有问题。我不得不对公司说,问题仍然存在并且将来可能会再次发生,但我不能等待SQA团队解决它。
感谢您的所有回复和时间