Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce generic assertion hooks in MockMvc #23330

Closed
sbrannen opened this issue Jul 22, 2019 · 8 comments
Closed

Introduce generic assertion hooks in MockMvc #23330

sbrannen opened this issue Jul 22, 2019 · 8 comments
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) status: duplicate A duplicate of another issue type: enhancement A general enhancement

Comments

@sbrannen
Copy link
Member

sbrannen commented Jul 22, 2019

Overview

As discussed in #21178 (comment), it would be possible to provide generic hooks in MockMvc APIs that allow one to use any assertion library of choice. Such generic hooks could even be used for purposes other than performing assertions.

Due to the usefulness of such general purpose hooks, we should consider introducing them in various MockMvc APIs even if we do not provide specific support for a fluent assertion API such as AssertJ (see gh-21178).

The introduction of such hooks would also align with similar support provided in WebTestClient -- for example, WebTestClient.BodySpec.value(Consumer<B>).

Deliverables

TBD

@sbrannen sbrannen added in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement labels Jul 22, 2019
@sbrannen sbrannen added this to the 5.2 RC1 milestone Jul 22, 2019
@rstoyanchev rstoyanchev modified the milestones: 5.2 RC1, 5.2 RC2 Aug 1, 2019
@sbrannen sbrannen modified the milestones: 5.2 RC2, 5.x Backlog Sep 3, 2019
@simonbasle
Copy link
Contributor

simonbasle commented Dec 22, 2022

This could be implemented as a satisfies(Consumer<B>) method on various xxxResultMatchers classes of the MockMvc hierarchy. The naming is borrowed from AssertJ's own similar consumer-based assertion.

for instance, to assert/consume status codes, we'd add this to StatusResultMatchers:

public ResultMatcher satisfies(IntConsumer satisfyConsumer) {
	return result -> satisfyConsumer.accept(result.getResponse().getStatus());
}

usage example with AssertJ:

this.mockMvc.perform(post("/persons"))
	.andExpect(status().satisfies(code -> Assertions.assertThat(code).isBetween(100, 300)));

The relevant resultmatchers seems to be most classes in org.springframework.test.web.servlet.result:

  • ContentResultMatchers
  • CookieResultMatchers
  • FlashAttributeResultMatchers
  • HandlerResultMatchers
  • HeaderResultMatchers
  • JsonPathResultMatchers
  • ModelResultMatchers
  • RequestResultMatchers
  • StatusResultMatchers
  • ViewResultMatchers
  • XpathResultMatchers

@simonbasle simonbasle self-assigned this Dec 22, 2022
@simonbasle
Copy link
Contributor

some of these seem to have multiple "target" that they internally use. eg. StatusResultMatchers targets primarily result.getResponse().getStatus() but also has a few methods targeting result.getResponse().getErrorMessage()... 🤔

@simonbasle simonbasle added the status: pending-design-work Needs design work before any code can be developed label Dec 22, 2022
@simonbasle simonbasle removed their assignment Jan 24, 2023
@sbrannen
Copy link
Member Author

some of these seem to have multiple "target" that they internally use. eg. StatusResultMatchers targets primarily result.getResponse().getStatus() but also has a few methods targeting result.getResponse().getErrorMessage()... 🤔

Indeed. The single satisfies(Consumer<B>) method approach seems quite elegant until you run into collisions for the same type (e.g., String for character encoding vs. expected content in ContentResultMatchers).

Thanks for brainstorming though! 👍

It's good to toss around a few ideas.

@sbrannen
Copy link
Member Author

sbrannen commented Feb 21, 2023

Though, perhaps it's not so bad to introduce sibling consumer methods like:

  • StatusResultMatchers#codeSatisfies(IntConsumer action)
    • status().codeSatisfies(code -> assertThat(code).isEqualTo(200))
    • or perhaps better: status().code(code -> assertThat(code).isEqualTo(200))
  • StatusResultMatchers#reasonSatisfies(Consumer<String> action)
    • status().reasonSatisfies(reason -> assertThat(reason).isEqualTo("Expired token"))
    • or perhaps better: status().reason(reason -> assertThat(reason).isEqualTo("Expired token"))

or similarly:

  • ContentResultMatchers#encoding(Consumer<String> action)
    • content().encoding(encoding -> assertThat(encoding).isEqualTo("UTF-8"))
  • ContentResultMatchers#string(Consumer<String> action)
    • content().string(body -> assertThat(body).contains("hello"))

@simonbasle & @rstoyanchev, thoughts?

@sbrannen sbrannen modified the milestones: 6.x Backlog, 6.0.x Feb 21, 2023
@nightswimmings
Copy link

nightswimmings commented Feb 25, 2023

I like more the Satisfies approach, even though is much more verbose, it is clear in its intention (just a personal opinion)

@sbrannen
Copy link
Member Author

I like more the Satisfies approach, even though is much more verbose, it is clear in its intention

Do you mean the variants like the following?

  • status().codeSatisfies(code -> assertThat(code).isEqualTo(200))

@sbrannen sbrannen modified the milestones: 6.0.x, 6.1.x Mar 7, 2023
@jhoeller jhoeller modified the milestones: 6.1.x, 6.x Backlog Nov 9, 2023
@sbrannen
Copy link
Member Author

@bclozel and @snicoll, would you consider this superseded by your work on #21178?

@bclozel
Copy link
Member

bclozel commented Mar 12, 2024

To me this looks like a duplicate of #21178 in the first place, so yes let's close it.

@snicoll snicoll closed this as not planned Won't fix, can't repro, duplicate, stale Mar 12, 2024
@snicoll snicoll added status: duplicate A duplicate of another issue and removed status: pending-design-work Needs design work before any code can be developed labels Mar 12, 2024
@snicoll snicoll removed this from the 6.x Backlog milestone Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) status: duplicate A duplicate of another issue type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

7 participants