【问题标题】:Getting java.lang.AbstractMethodError when I test using REST Assured使用 REST Assured 进行测试时出现 java.lang.AbstractMethodError
【发布时间】:2020-07-16 02:43:48
【问题描述】:

我正在尝试使用 REST Assured v4.3.0 测试在我的控制器类中定义的 REST api,但是在运行测试时我得到了 java.lang.AbstractMethodError。我知道这个错误正在发生,因为我正在调用一个抽象方法,但我很难解决它。

似乎由于SampleControllerTest.java 中的.body(is(equalTo("success"))) 而发生错误,因为当我删除此行时,测试成功。我尝试了一些方法来解决它,但没有成功:

  • 在线搜索建议和示例,但它们要么是旧版本,要么与io.rest-assured/spring-mock-mvc无关
  • 尝试了不同的匹配器(org.hamcrest.Matchers.*org.hamcrest.CoreMatchers.*
  • 尝试在 pom 文件中显式添加 org.hamcrest/hamcrest 依赖项

这是我的代码供您参考:

代码结构:

test
|- src/
|  |- main/
|  |  |- java/
|  |  |  |- org/
|  |  |  |  |- example/
|  |  |  |  |  |- Application.java
|  |  |  |  |  |- SampleController.java
|  |- test/
|  |  |- java/
|  |  |  |- org/
|  |  |  |  |- example/
|  |  |  |  |  |- SampleControllerTest.java
|- target/
|- pom.xml

Application.java

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

SampleController.java

package org.example;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SampleController {
    @RequestMapping(value = "/sample")
    @ResponseStatus(value = HttpStatus.OK)
    public String getSample() {
        return "success";
    }
}

SampleControllerTest.java

package org.example;

import org.junit.Test;

import static io.restassured.module.mockmvc.RestAssuredMockMvc.*;
import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

public class SampleControllerTest {
    @Test
    public void testGetSample() {
        given()
            .standaloneSetup(new SampleController())
            .when()
            .get("/sample")
            .then()
            .assertThat(status().isOk())
            .body(is(equalTo("success")));
    }
}

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">
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.example</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <java.version>8</java.version>
        <start-class>org.example.Application</start-class>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- JUnit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.rest-assured/spring-mock-mvc -->
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>spring-mock-mvc</artifactId>
            <version>4.3.0</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.rest-assured/json-path -->
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>json-path</artifactId>
            <version>4.3.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.rest-assured/xml-path -->
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>xml-path</artifactId>
            <version>4.3.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>4.3.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

当我使用mvn test 运行测试时,这是我得到的错误:

[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.325 s <<< FAILURE! - in org.example.SampleControllerTest
[ERROR] testGetSample(org.example.SampleControllerTest)  Time elapsed: 1.288 s  <<< ERROR!
java.lang.AbstractMethodError: Method io/restassured/internal/ResponseSpecificationImpl.getProperty(Ljava/lang/String;)Ljava/lang/Object; is abstract
        at org.example.SampleControllerTest.testGetSample(SampleControllerTest.java:20)

提前感谢您的帮助!

【问题讨论】:

    标签: java spring-boot maven junit rest-assured


    【解决方案1】:

    由于放心4.3.0将Groovy从2.5.7升级到3.0.2,见rest-assured/changelog.txt at master · rest-assured/rest-assured,可以在pom文件中指定groovy版本。

      <properties>
        <rest-assured.version>4.3.0</rest-assured.version>
        <groovy.version>3.0.2</groovy.version>
      </properties>
    

    【讨论】:

    • 对于 Gradle,应该是 ext["groovy.version"] = "3.0.3" (Groovy DSL) 或 extra.apply { set("groovy.version", "3.0.3") } (Kotlin DSL)。
    【解决方案2】:

    这看起来像是 REST Assured 4.3.0 中的一个错误,您的代码适用于 4.2.0 版本。

    我没有找到打开的问题。 https://github.com/rest-assured/rest-assured/issues

    【讨论】:

    • 这可能是真的。当我删除 io.rest-assured/rest-assured 依赖并保留 io.rest-assured/spring-mock-mvc 时,它工作正常。
    • Ops...我做你做的事,也能工作!我从 "io.rest-assured/rest-assured" 更改为 io.rest-assured/spring-mock-mvc 并添加 pom.xml xml &lt;io-rest-assured.version&gt;4.3.0&lt;/io-rest-assured.version&gt; &lt;dependency&gt; &lt;groupId&gt;io.rest-assured&lt;/groupId&gt; &lt;artifactId&gt;spring-mock-mvc&lt;/artifactId&gt; &lt;version&gt;${io-rest-assured.version}&lt;/version&gt; &lt;scope&gt;test&lt;/scope&gt; &lt;/dependency&gt;
    • 不,这不是 REST Assured 中的错误,而是依赖项解析中的错误。有些东西(在这种情况下是 Spring)依赖于 Groovy 2.1.3(对于所有工件)。 REST Assured 依赖于 Groovy 3.0.2(或 3.0.3),但仅声明顶级依赖项,而不是 org.codehaus.groovy:groovy 本身 - Spring 胜出。
    【解决方案3】:

    我使用 4.2.0 而不是 4.3.0 .. 它对我有用

    【讨论】:

    • 我使用@jörg-pfründer 评论上面的分辨率,它适用于我在 build.gradle 中放入的 4.3.1 版本:groovy configurations.all { resolutionStrategy.cacheDynamicVersionsFor 10, "minutes" resolutionStrategy.eachDependency { DependencyResolveDetails details -&gt; if (details.requested.group == 'org.codehaus.groovy') { details.useVersion "3.0.2" details.because "needed by rest-assured&gt;=4.3" } } }
    【解决方案4】:

    对于 Maven 项目,以下代码适用于 Spring Boot 项目:

    <properties>
           <groovy.version>3.0.7</groovy.version>
           <rest-assured.version>4.3.3</rest-assured.version>
       </properties>
    
       <dependencies>
           <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter</artifactId>
           </dependency>
           <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-test</artifactId>
               <scope>test</scope>
           </dependency>
           <dependency>
               <groupId>io.rest-assured</groupId>
               <artifactId>spring-mock-mvc</artifactId>
               <scope>test</scope>
               <exclusions>
                   <exclusion>
                       <artifactId>groovy</artifactId>
                       <groupId>org.codehaus.groovy</groupId>
                   </exclusion>
               </exclusions>
           </dependency>
           <dependency>
               <groupId>org.codehaus.groovy</groupId>
               <artifactId>groovy</artifactId>
               <version>${groovy.version}</version>
           </dependency>
           <dependency>
               <groupId>org.codehaus.groovy</groupId>
               <artifactId>groovy-xml</artifactId>
               <version>${groovy.version}</version>
           </dependency>
           <dependency>
               <groupId>org.codehaus.groovy</groupId>
               <artifactId>groovy-json</artifactId>
               <version>${groovy.version}</version>
           </dependency>
           <dependency>
               <groupId>io.rest-assured</groupId>
               <artifactId>json-path</artifactId>
               <version>${rest-assured.version}</version>
               <scope>test</scope>
           </dependency>
           <dependency>
               <groupId>io.rest-assured</groupId>
               <artifactId>xml-path</artifactId>
               <version>${rest-assured.version}</version>
               <scope>test</scope>
           </dependency>
       </dependencies>
    ```
    

    【讨论】:

      【解决方案5】:

      我也有一个java.lang.AbstractMethodError,但使用了另一种方法。

      rest-assured 4.3 升级了它的实现以使用groovy 3,见rest assured's release notes

      在我的例子中,依赖解析将 groovy 降级为使用一些 2.x 版本。

      如果你使用 maven:

      您可以使用mvn dependency:tree 进行检查。 如果存在冲突,请将必要的 groovy 依赖项作为版本=>3.0.2 的直接依赖项添加到您的项目中。

      如果你使用 gradle:

      您可以使用gradle depencencies 进行检查。 如果存在冲突,则添加解决策略:

      configurations.all {
          resolutionStrategy.eachDependency { DependencyResolveDetails details ->
              if (details.requested.group == 'org.codehaus.groovy') {
                  details.useVersion "3.0.2"
                  details.because "needed by rest-assured>=4.3"
              }
          }
      }
      

      也许这可以帮助某人。

      【讨论】:

      • 或者,也许更短或更易读:constraints { iplementation("org.codehaus.groovy:groovy:3.0.3") { because("Needed by REST Assured") } }
      【解决方案6】:

      如果您使用 Rest Assured 版本 4.3.2,只需明确将 groovy 版本指定为 3.0.6 即可修复错误。

      <rest-assured.version>4.3.2</rest-assured.version>
      <groovy.version>3.0.6</groovy.version>
      

      祝你好运。

      【讨论】:

        【解决方案7】:

        原来io.rest-assured/spring-mock-mvc 依赖与io.rest-assured/rest-assured 依赖冲突。一旦我从pom.xml 中删除了io.rest-assured/rest-assured,测试就成功了。

        几年前,当我使用 REST Assured 版本 3.1.1 时,我可以保留这两个依赖项,但也许新版本不允许这样做。

        【讨论】:

          【解决方案8】:

          在 pom.xml 中使用下面的放心依赖

              <dependency>
                  <groupId>io.rest-assured</groupId>
                  <artifactId>rest-assured</artifactId>
                  <version>4.2.0</version>
                  <scope>test</scope>
              </dependency>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-06-13
            • 1970-01-01
            • 2020-08-10
            • 1970-01-01
            • 2016-12-24
            • 2016-05-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多