java - 多个 Maven 模块来分离测试、API 和实现

标签 java maven junit

我想创建一个 Maven 项目,在一个 api 模块中声明的多个接口(interface)的单独模块中包含多个实现(对于上下文,我正在编写一个 java 持久性实验室,学生必须在其中实现多个对服务和存储库进行计时,从简单的 JDBC 到 JPA,然后是 spring-data-jpa)。

项目中有几个maven模块:

  • 根 maven multiple-modules 模块,包括三个子模块
  • api 模块,包含 API 接口(interface)
  • api-tests 模块,包含与 API 接口(interface)相关的测试
  • main 模块,包含 API 的实现之一

根项目模块

主maven项目声明了三个子模块:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.kartoch.stack</groupId>
    <artifactId>multiple-modules</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>api</module>
        <module>main</module>
        <module>tests</module>
    </modules>

</project>

API模块

API声明接口(interface):

public interface MustReturnTrue {

    boolean askMeTrue();
}

api子模块相关pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
              http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>multiple-modules</artifactId>
        <groupId>org.kartoch.stack</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>api</artifactId>


</project>

测试模块

在此模块中,测试是针对 API 接口(interface)编写的:

import org.junit.Test;

import static org.junit.Assert.assertTrue;

public class MustReturnTrueTest extends Template {


    @Test
    public void testAskMeTrue() {
        assertTrue(mustReturnTrue.askMeTrue());
    }
}

由于API接口(interface)的实现是子模块依赖的,所以测试包中提供了一个抽象类,需要在各个实现模块中实现:

public abstract class Template {

    public MustReturnTrue mustReturnTrue;
}

对于这两个类,代码位于 src/main/java 目录中,而不是 src/test/java 目录中,因为我使用 the preferred way to create a jar containing test classes :

测试子模块的相关pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
              http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>multiple-modules</artifactId>
        <groupId>org.kartoch.stack</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>api-tests</artifactId>


    <dependencies>
        <dependency>
            <groupId>org.kartoch.stack</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

</project>

主模块

最后,主模块包含 API 接口(interface)的一个实现(在 src/main/java 中):

公共(public)类 MustReturnTrueImpl 实现 MustReturnTrue { 公共(public) boolean askMeTrue(){ 返回真; } }

以及测试的模板实现(在src/test/java中):

import org.junit.Before;

public class TemplateInitialization extends Template {

    @Before
    public void before() {
        mustReturnTrue = new MustReturnTrueImpl();
    }
}

主子模块相关pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>multiple-modules</artifactId>
        <groupId>org.kartoch.stack</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>

    <artifactId>main</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.kartoch.stack</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.kartoch.stack</groupId>
            <artifactId>api-tests</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

问题

我在测试期间期望的是,测试模块中的测试是在实现 Template 的类初始化实现后针对实现执行的。

但由于未知原因,测试在 main 测试生命周期期间未执行:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------

Results :

Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

有什么想法吗?

编辑 1

我的印象是问题是继承没有按预期工作。由于 TemplateInitialization 继承了不包含测试的 Template,因此不会执行任何测试:MustReturnTrueTest 中的测试不会“神奇地”导入。我需要一种在测试之前在运行时加载 TemplateInitialization 的方法。

最佳答案

您的模板初始化应该直接在测试类中完成:

import org.junit.Test;

import static org.junit.Assert.assertTrue;

public class MustReturnTrueTest extends Template {

    @Before
    public void before() {
        mustReturnTrue = new MustReturnTrueImpl();
    }

    @Test
    public void testAskMeTrue() {
        assertTrue(mustReturnTrue.askMeTrue());
    }
}

如果您需要在每次测试之前进行实例化,请使用 JUnit @Before 注释。

如果您需要在测试类中的所有测试之前实例化一次,请使用@BeforeClass

<小时/>

编辑:

我建议您按照 Maven 标准将测试放在实现代码中(在主项目中)。

关于java - 多个 Maven 模块来分离测试、API 和实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38303534/

相关文章:

java - 带有 Rest 的 Apache AVRO

junit - 使用 Maven 从 @Category 运行所有测试

Java 套接字服务器,位于集群服务器上

java - 谁在调用 paintComponent?

eclipse - 在 Eclipse 中使用 Jetty Maven 插件在多模块项目 : Compilation unit not on the build path 上进行调试

java - 如何查找未使用的maven依赖?

ant - 如何将 build.xml 转换为 maven pom 文件?

java - 使用 jUnit 测试单例

java - 测试产生随机结果的方法

java - 我怎样才能从另一个源 jar 重建一个源 jar ?