解决遗留junit测试套件中的java类路径地狱

解决遗留junit测试套件中的java类路径地狱,java,junit,dependencies,classpath,Java,Junit,Dependencies,Classpath,假设我有一个遗留JUnit测试套件,其中包括以下测试: public class AwesomeTest { public void testBusinessLogic() { ... [awesome mocking library] ... } } public class AmazingTest { public void testBusinessProcess() { ... [amazing xml opera

假设我有一个遗留JUnit测试套件,其中包括以下测试:

public class AwesomeTest {
     public void testBusinessLogic() {
     ...
     [awesome mocking library]
     ...
     }
}

public class AmazingTest {
    public void testBusinessProcess() {
    ...
    [amazing xml operation]
    ...
    }
}
现在假设Awesome Mocking库依赖于Awesome BCEL字节码生成库,该库包含类
org.usiver.XMLClass
,并且该库具有XMLClass的版本1

现在假设惊人的Xml操作依赖于惊人的Xml库,该库包含类
org.usiver.XMLClass
,并且该库具有Xml类的版本2

还假设类的版本2与版本1不向后兼容-因此哪个版本在类路径中具有更高的优先级-它会破坏其他版本的依赖关系

还假设有400个测试依赖于可怕的模拟库,所以重写不是一个理想的选择

还假设一些关键的业务特性是用惊人的xml库构建的,强烈建议不要重写这些特性


除了使用两个不同的手动排序的类路径和手动确定的测试子集运行两次ant测试(假设您使用ant)之外,您如何解决这个类路径地狱的情况?(我对使用自定义类加载器的想法持开放态度,但这似乎与使用ant解决方案的双自定义类路径具有相同的可维护性级别)

我确实相信使用java代理和自定义类加载器可以获得一个相当透明的解决方案。其思路如下:

  • 加载类时,使用(java代理)截取类。当您检测到Awesome Mocking库中的类时,请将对
    org.usiver.XMLClass
    的所有引用替换为,例如,
    intercepted.org.usiver.XMLClass
  • 创建一个自定义类加载器,在该加载器中检查请求的类是否被拦截。如果是,请加载模拟库使用的
    XMLClass
    版本。默认情况下,可以处理所有其他请求

  • 在运行测试时,使用自定义类加载器并附加java代理,一切都应该正确运行,就好像没有依赖冲突一样。

    我认为Steven的回答很好-为了完整性,并且因为这个问题获得了这么多选票-我想分享我们想到的所有备选方案(包括不好的方案)

  • 将测试(或部分测试)划分为不同的类路径顺序 (缺点-可能导致您错过测试中的其他重要问题-不是可行的选择)
  • 回滚惊人的xml操作并以另一种方式实现(考虑到在使用此操作方面的投资,以及其他操作已经用尽的事实,此操作已被忽略)
  • 使用一个新的模拟库重写测试(从长远来看这是很好的-从短期来看,这比我们当前的项目要大,因为有成百上千个)
  • 构建一个定制版本的惊人模拟库,该库使用较新版本的
    org.usivery.XMLClass
    (结果比我们当前的项目要大)
  • 从源代码中提取出有问题的类,并将较旧的版本放在覆盖源代码库的测试类路径上(结果表明这与其他几个类纠缠在一起——因此这是非常重要的)
  • 使用上面史蒂文的绝妙想法——这再次证明是不平凡的
  • 使用@Ignore-设置测试,并将它们放入队列中,以便在将来的项目中重写

  • 是的,没关系。故障似乎出在首先捆绑XML文件的字节码生成器上。我建议你更新你的模拟库。也许你可以得到“很棒的BCEL字节码生成库”的源代码,并创建一个依赖于类org.usefulous.XMLClass重命名版本的fork。我同意没有简单的答案。您可以尝试使用自定义类装入器,也许。。。但这似乎比它的价值更大。我已经用一个新的库为XML或模拟操作重写了测试,这太棒了。有没有一种方法可以加载现有类路径的副本版本并在运行时对其进行修改(即效果相同但不使用代理)?我不完全确定这是什么意思,但如果不使用代理来区分XMLClass的不同版本,运行时将如何决定从哪一点使用哪个版本?