Skip to content

Error when using JsonPathAssertions and RestTestClient #48048

@edwardsre

Description

@edwardsre

When using a RestTestClient in a WebMvcTest created with @AutoConfigureRestTestClient, I am getting an error using json path assertions and ParameterizedTypeReference. The WebTestClient works correctly.

It appears RestTestClient is using JsonSmartMappingProvider by default which says it doesn't support this. I haven't been able to determine a way to configure it to use Jackson or Gson as suggested in the error message.

I would expect that RestTestClient would work the same way as WebTestClient.

Error stack trace:

java.lang.AssertionError: Failed to evaluate JSON path "$.messages[*]"
	at org.springframework.test.util.JsonPathExpectationsHelper.evaluateExpression(JsonPathExpectationsHelper.java:406)
	at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:381)
	at org.springframework.test.web.support.AbstractJsonPathAssertions.value(AbstractJsonPathAssertions.java:181)
	at com.example.demo.DemoApplicationTests.restTestClient(DemoApplicationTests.java:35)
Caused by: java.lang.UnsupportedOperationException: Json-smart provider does not support TypeRef! Use a Jackson or Gson based provider
	at com.jayway.jsonpath.spi.mapper.JsonSmartMappingProvider.map(JsonSmartMappingProvider.java:94)
	at com.jayway.jsonpath.internal.JsonContext.convert(JsonContext.java:121)
	at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:103)
	at org.springframework.test.util.JsonPathExpectationsHelper.lambda$evaluateJsonPath$1(JsonPathExpectationsHelper.java:382)
	at org.springframework.test.util.JsonPathExpectationsHelper.evaluateExpression(JsonPathExpectationsHelper.java:402)

This is my test class:

@WebMvcTest
@AutoConfigureRestTestClient
@AutoConfigureWebTestClient
class DemoApplicationTests {

  @Autowired
  RestTestClient restTestClient;

  @Autowired
  WebTestClient webTestClient;

	@Test // fails with error
	void restTestClient() {
    restTestClient.get()
      .uri("/test")
      .exchange()
      .expectStatus().isOk()
      .expectBody().jsonPath("$.messages[*]")
      .value(new ParameterizedTypeReference<@NonNull List<String>>() {},
             messages -> assertThat(messages).contains("hello", "world!"));
	}

	@Test // works correctly
	void webTestClient() {
    webTestClient.get()
      .uri("/test")
      .exchange()
      .expectStatus().isOk()
      .expectBody().jsonPath("$.messages[*]")
      .value(new ParameterizedTypeReference<@NonNull List<String>>() {},
             messages -> assertThat(messages).contains("hello", "world!"));
	}

}

This is a demo application to run the test against:

@SpringBootApplication
@RestController
public class DemoApplication {

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

  @GetMapping("/test")
  public Greeting test() {
    return new Greeting(List.of("hello", "world!"));
  }

  public record Greeting(List<String> messages) {
  }

}

Maven pom dependencies:

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

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webmvc-test</artifactId>
    <scope>test</scope>
  </dependency>

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-webtestclient</artifactId>
    <scope>test</scope>
  </dependency>

</dependencies>

Metadata

Metadata

Assignees

No one assigned

    Labels

    for: external-projectFor an external project and not something we can fix

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions