【问题标题】:gradle test fail when using compileOnly and testCompileOnly使用 compileOnly 和 testCompileOnly 时 gradle 测试失败
【发布时间】:2017-11-14 06:26:51
【问题描述】:

我有一个小的 gradle 库项目,它只有两个文件和两个测试:

RandomUtils.java

final class RandomUtils {

    private static final SecureRandom random = new SecureRandom();

    private RandomUtils() {
    }

    static String nextRandomId() {
        return new BigInteger(130, random).toString(32);
    }

}

URLUtils.java:

public class URLUtils {

    private URLUtils() {
    }

    /**
     * Return the base url (eg: http://localhost:8080)
     * @param request
     * @return String
     * @throws MalformedURLException
     */
    public static String getURLBase(HttpServletRequest request) throws MalformedURLException {
        URL requestURL = new URL(request.getRequestURL().toString());
        String port = requestURL.getPort() == -1 ? "" : ":" + requestURL.getPort();
        return requestURL.getProtocol() + "://" + requestURL.getHost() + port;
    }

}

这些是相应的测试:

@RunWith(JUnit4.class)
public class RandomUtilsTest {

    @Test
    public void testConstructorIsPrivate() throws Exception {
        Constructor constructor = RandomUtils.class.getDeclaredConstructor();
        assertTrue(Modifier.isPrivate(constructor.getModifiers()));
        constructor.setAccessible(true);
        constructor.newInstance();
    }

    @Test
    public void nextRandomId() throws MalformedURLException {
        assertNotNull(RandomUtils.nextRandomId());
    }

}

@RunWith(JUnit4.class)
public class URLUtilsTest {

    @Test
    public void testConstructorIsPrivate() throws Exception {
        Constructor constructor = URLUtils.class.getDeclaredConstructor();
        assertTrue(Modifier.isPrivate(constructor.getModifiers()));
        constructor.setAccessible(true);
        constructor.newInstance();
    }
    @Test
    public void getURLBase() throws MalformedURLException {
        MockHttpServletRequest request = new MockHttpServletRequest();
        request.setRequestURI("/entity");
        assertEquals("http://localhost", URLUtils.getURLBase((HttpServletRequest) request));
        request.setRequestURI(":8080/entity");
        assertEquals("http://localhost:8080", URLUtils.getURLBase((HttpServletRequest) request));
    }

}

我有以下build.gradle

dependencies {
    compileOnly("javax.servlet:javax.servlet-api:${javaxServletApiVersion}")
    testCompileOnly("javax.servlet:javax.servlet-api:${javaxServletApiVersion}")
    testCompileOnly("org.springframework:spring-test:${springVersion}")
    testCompileOnly("junit:junit:${junitVersion}")
}

我在 intellij 中对依赖项没有任何问题,但是当我尝试运行 ./gradlew clean build 时,我在运行任务 :common:webutils:test 时出现此错误:

java.lang.NoClassDefFoundError: org/springframework/mock/web/MockHttpServletRequest
    at com.domain.api.common.webutils.URLUtilsTest.getURLBase(URLUtilsTest.java:27)

我查看了 gradle documentation,上面写着

  • compileOnly:仅编译时的依赖项,不在运行时使用
  • testCompileOnly:仅用于编译测试的附加依赖项,不在运行时使用

我的配置正确吗?如果 javax.servlet:javax.servlet-api:${javaxServletApiVersion} 同时存在于 test 和 src 中,为什么它会在测试中失败?

【问题讨论】:

    标签: java servlets intellij-idea gradle build.gradle


    【解决方案1】:

    您已经回答了自己的问题:

    testCompileOnly:附加依赖仅用于编译测试,不在运行时使用

    testCompileOnly 仅在编译测试时可用,而不是在执行测试时可用。如果您只在测试执行时需要一些东西,而不是像slf4j 绑定或类似的编译,那属于testRuntime。如果你需要一些东西来编译测试和运行时,那么它属于testCompile

    【讨论】:

    • +1 以获得这个有用的答案。否则,我不使用 Gradle ;-) 我尝试依赖文档,但我没有管理。我觉得真的不太清楚。 “默认情况下,还包括编译、运行时和测试编译依赖项。”似乎意味着它在测试执行期间也可用。
    • 不,你反过来读。没有写 testRuntime 在 compile 可用的地方可用,有写 testRuntime 包含 compile 因此是一个超集。我发现文档对此非常清楚。 :-)
    猜你喜欢
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多