【问题标题】:Resolving Maven circular dependencies between test, testhelper, and project-under-test解决测试、testhelper 和被测项目之间的 Maven 循环依赖关系
【发布时间】:2012-04-27 19:22:52
【问题描述】:

我的设置是这样的。我有项目A,还有一个依赖A的测试项目:

A <- A_t

我还有其他项目取决于A(及其测试):

A <- B <- B_t

为了简化一些测试,我引入了一个新的库来帮助测试基于 A 的东西:

A <- Atesthelper

所以A_t(和B_t)将依赖于这个测试助手,像这样:

A <- A_t
^    |
|    v
Atesthelper

但是,当我创建 Maven 项目 (pom.xml) 时,通常的做法是将项目和该项目的测试捆绑在同一个 pom.xml 中。我为Atesthelper创建了一个新的 pom.xml

所以现在变成了:

(A <- A_t)
  ^    |
  |    v
Atesthelper

这是一个循环依赖。是否可以在 pom.xml 中以某种方式指定 Atesthelper 只是测试构建目标的依赖项,而不是 A 模块本身?

所以构建顺序应该是:A、Atesthelper、A_t。 IE。 A 和 A_t 在同一个 pom 中指定,不能同时构建。

提前致谢。

【问题讨论】:

  • 如果您从项目的 pom 中粘贴相关摘录,这将非常有帮助。

标签: unit-testing maven maven-2 dependencies circular-dependency


【解决方案1】:

解决此问题的最简洁方法是将项目分开。像 Maven 这样的框架鼓励您将类和测试类放在一个项目中。例如,Eclipse 插件项目有单独的测试项目。将A_t 设为A 的子项目听起来是最好的解决方案,因为您可以在该测试项目中重用您想要的任何依赖项,而不必担心对A 的影响。

这种情况会更频繁地出现,您可能不想因为测试的依赖关系而打扰您的项目设计。这些测试应该是独立的,不会影响你的类设计。

【讨论】:

    【解决方案2】:

    如果我理解正确,您的主要目标是重用测试类。 A_t 和 Atesthelper 不是 Maven 项目,它们是测试。

    让 Maven 从你的 src/test/java 创建一个 jar。见http://maven.apache.org/guides/mini/guide-attached-tests.html

    构建 A 后,您将获得 A.jar 和 A-tests.jar。 A-tests.jar 将包括 Atesthelper 和 A_t。

    将 B 的依赖设置为 A-tests.jar (&lt;type&gt;test-jar&lt;/type&gt;).

    【讨论】:

      【解决方案3】:

      你需要解决的问题是 AtesthelperA 的依赖关系,那么其他一切都会正常工作:A 依赖于 Atesthelper, B 依赖于 Atesthelper 并且 AB 都将包含源和测试。 Atesthelper 将包含在 AB 中的范围 test 中。那是你的目标状态。

      你怎么去那里?您需要将 Atesthelper 所依赖的项目提取到单独的项目中。通常,这些是接口或其他通用功能,无论如何都应该放入单独的项目中 - 我们称之为 ACommon。所以你的目标布局应该是这样的:

      ACommon <- Atesthelper
             ^    ^
             |   /
               A (and also B)
      

      Atesthelper 依赖于 A 中的哪些功能?你能把它移到一个单独的项目(ACommon)吗?

      【讨论】:

      • Atesthelper 必须依赖于 A,因为它实际上是测试 A 中的内容的助手,因此依赖于 A 中的许多纯数据对象并与A。所以我认为这不是正确的依赖关系。我希望得到有关如何配置 maven 以分别构建 AA_t 的答案。
      • 这对我来说听起来像是一个设计问题。您正在尝试与 Maven 处理项目和依赖项的方式作斗争:一个项目,一个工件。您也许可以根据自己的需要对其进行调整,但从长远来看,这会给您带来更多麻烦。保持简单并坚持 Maven 做事的方式。顺便说一句:Bob 大叔在很多年前也描述过类似的东西——依赖倒置原则,值得一读:objectmentor.com/resources/articles/dip.pdf
      • 所以 Maven 规定了一个项目一个工件。因此,A 应该有一个项目(又名 pom.xml),A_t 应该有另一个项目。这将解决问题,但我认为您“通常”将项目和测试放在同一个 pom.xml 中。我了解(并使用)DI,但在这种情况下您会注入哪种依赖项?
      • 这篇文章是关于依赖inversion,而不是injection。两种不同的东西。实现和测试都应该在同一个项目中,这是标准设置。我的建议是打破你的项目 A 和测试助手类之间的依赖关系。
      【解决方案4】:

      你没有粘贴你的 POM,我不确定我是否正确理解你,但我会尽力帮助你我是如何得到它的。这是很常见的情况,通常应该这样解决:

      您的支持测试的Atesthelper 工件(可能是jar 包装)应该在src/main 目录中包含所有与测试相关的内容(因此src/main/java 中的类,src/main/resources 中的资源等) ),而不是src/test!它的所有依赖项,所以A,还有像JUnit、EasyMock(测试支持类需要的所有东西)你用compile范围声明的东西,当然这是默认的。不要在这里使用test 范围!最后,在AB 工件中,将Atesthelper 声明为test 范围的依赖项。

      多年来,该解决方案对我来说非常有效。它对依赖项干净而直接(如果您知道我的意思,它们与基于&lt;type&gt;test-jar&lt;/type&gt; 的解决方案相比是可传递的)。无论如何,只是使用它。你会很开心;)。

      【讨论】:

      • 没有解决循环依赖的问题。
      • 我认为循环依赖问题会通过使用这个解决方案而消失。正如我所说,我从来没有遇到过任何问题。恕我直言,它应该工作得很好。
      • 我想如果你先用skipping the tests构建AB,然后构建Atesthelper,然后再通过测试构建AB,这可能会起作用。
      • @MichalKalinowski:这是我尝试过的(有点),我认为正确使用范围应该是解决方案。但是,我无法解决 AA_t 不应该紧跟其后构建的问题,首先是 A,然后是 Atesthelper,然后是 A_t,我不知道 maven 何时可以做到这一点AA_t 在同一个 pom.xml 中指定?
      • 这正是问题所在,你写了一个Module A和一个Module B。B依赖A,到目前为止没有问题。现在您要为模块 A:AT 编写测试。 AT 现在显然依赖于 A,但也可以依赖于 B。对于这三个项目,完全没有问题。但是 maven 结构鼓励将 AT 中的所有内容放入 A 的测试文件夹中,这会导致 A(因为 AT)依赖于 B,而 B 依赖于 A 的问题。
      猜你喜欢
      • 1970-01-01
      • 2016-08-12
      • 2022-10-04
      • 1970-01-01
      • 2014-09-05
      • 2021-08-24
      • 2014-02-26
      • 1970-01-01
      • 2019-03-16
      相关资源
      最近更新 更多