16

I'm trying to test a REST api defined in my controller class using REST Assured v4.3.0, but I get java.lang.AbstractMethodError when I run the test. I understand this error is occurring because I'm calling an abstract method, but I'm having a hard time resolving it.

It seems that the error is occurring due to .body(is(equalTo("success"))) in SampleControllerTest.java because when I remove this line, the test succeeds. I tried a few things to resolve it, but didn't get any success:

  • Searched online for suggestions and examples, but they are either for older versions or not related to io.rest-assured/spring-mock-mvc
  • Tried different matchers (org.hamcrest.Matchers.* and org.hamcrest.CoreMatchers.*)
  • Tried adding org.hamcrest/hamcrest dependency in the pom file explicitly

Here's my code for your reference:

Code structure:

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>

When I run the test using mvn test, this is the error I get:

[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)

Thanks for any help in advance!

pgngp
  • 1,552
  • 5
  • 16
  • 26

8 Answers8

16

Because of rest-assured 4.3.0 upgrade the Groovy from 2.5.7 to 3.0.2, see rest-assured/changelog.txt at master · rest-assured/rest-assured, you can specified the groovy version in pom file.

  <properties>
    <rest-assured.version>4.3.0</rest-assured.version>
    <groovy.version>3.0.2</groovy.version>
  </properties>
cheng1243
  • 171
  • 1
  • 3
  • For Gradle, that would be `ext["groovy.version"] = "3.0.3"` (Groovy DSL) or `extra.apply { set("groovy.version", "3.0.3") }` (Kotlin DSL). – Michael Piefel Aug 19 '20 at 10:15
9

It looks like a bug in REST Assured 4.3.0, your code works with 4.2.0 version.

I didn't find opened issue. https://github.com/rest-assured/rest-assured/issues

Yan
  • 318
  • 2
  • 10
  • That might be true. When I removed the `io.rest-assured/rest-assured` dependency and kept `io.rest-assured/spring-mock-mvc`, it worked fine. – pgngp Apr 03 '20 at 21:36
  • Ops... I do what you do and works too! I change from "io.rest-assured/rest-assured" to io.rest-assured/spring-mock-mvc And add in pom.xml ```xml 4.3.0 io.rest-assured spring-mock-mvc ${io-rest-assured.version} test ``` – Igor Ferreira Jun 29 '20 at 02:57
  • 2
    No, it is not a bug in REST Assured, but in the dependency resolution. Something (Spring in this case) depends on Groovy 2.1.3 (for all artifacts). REST Assured depends on Groovy 3.0.2 (or 3.0.3), but declares only top-level dependencies, not `org.codehaus.groovy:groovy` itself – Spring wins. – Michael Piefel Aug 19 '20 at 10:13
6

I used 4.2.0 instead of 4.3.0 .. it works for me

zxinyan
  • 81
  • 4
  • Im use resolution above comment by @jörg-pfründer its works for with 4.3.1 version I put in build.gradle this: ```groovy configurations.all { resolutionStrategy.cacheDynamicVersionsFor 10, "minutes" resolutionStrategy.eachDependency { DependencyResolveDetails details -> if (details.requested.group == 'org.codehaus.groovy') { details.useVersion "3.0.2" details.because "needed by rest-assured>=4.3" } } } ``` – Igor Ferreira Aug 10 '20 at 13:20
5

For Maven projects, the code below works well with Spring Boot projects:

<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>
```
Moncef AOUDIA
  • 647
  • 8
  • 14
4

I also had an java.lang.AbstractMethodError but on another method.

rest-assured 4.3 upgraded it's implementation to use groovy 3, see rest assured's release notes

In my case the dependency resolution downgraded groovy to use some 2.x version.

If you use maven:

You can check that using mvn dependency:tree. If there's a conflict, add the necessary groovy dependencies as direct dependencies with a version=>3.0.2 to your project.

If you use gradle:

You can check that using gradle depencencies. If there's a conflict, then add a resolution strategy:

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"
        }
    }
}

Maybe that can help somebody.

Jörg Pfründer
  • 341
  • 3
  • 5
  • Or, perhaps shorter or more readable: `constraints { iplementation("org.codehaus.groovy:groovy:3.0.3") { because("Needed by REST Assured") } }` – Michael Piefel Aug 19 '20 at 10:19
2

Use below dependency of rest assured in pom.xml

    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>4.2.0</version>
        <scope>test</scope>
    </dependency>
user3729220
  • 230
  • 2
  • 8
2

If you use Rest Assured version 4.3.2, just specify explictly the groovy version to 3.0.6 and that fixes the error.

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

Good luck.

turong
  • 1,474
  • 9
  • 14
1

It turns out that io.rest-assured/spring-mock-mvc dependency was conflicting with io.rest-assured/rest-assured dependency. Once I removed the io.rest-assured/rest-assured from pom.xml, the test worked successfully.

A few years ago when I was using REST Assured version 3.1.1, I could keep both of these dependencies, but perhaps newer versions don't allow this.

pgngp
  • 1,552
  • 5
  • 16
  • 26