In REST Assured, what does MatcherConfig.errorDescriptionType change in a failed body assertion's message?
answer
- one setting on MatcherConfig
- two constants only
- REST_ASSURED is the default
- changes the Actual half only
- HAMCREST delegates to describeMismatch
basics
~20 sMatcherConfig.errorDescriptionType picks who describes the actual value when a REST Assured body expectation fails. The default, REST_ASSURED, prints the extracted value itself; HAMCREST calls the matcher's own describeMismatch instead. The enum has exactly those two constants.
solid answer
~50 s`MatcherConfig` is one of the eighteen config objects on `RestAssuredConfig`, and its only setting is `errorDescriptionType(ErrorDescriptionType)`, whose enum has exactly two constants: `REST_ASSURED` (the default) and `HAMCREST`. Both styles print the same first line — `JSON path <path> doesn't match.` or `XML path ...` — and the same `Expected:` half, which comes from the matcher's own description. They differ only in the `Actual:` half. Under `REST_ASSURED`, REST Assured renders the extracted value itself and strips the surrounding quotes off strings, so you see `Actual: Hereford`. Under `HAMCREST`, REST Assured calls `matcher.describeMismatch(...)`, so the matcher explains its own failure: a plain matcher prints `was "Hereford"`, and a collection matcher such as `hasItem` prints a per-element breakdown. Set it with `given().config(config().matcherConfig(matcherConfig().errorDescriptionType(HAMCREST)))`. It changes formatting only — the same expectations pass and fail either way, and the same `AssertionError` is thrown.
code
java · 18 linesimport io.restassured.config.MatcherConfig;
import static io.restassured.RestAssured.given;
import static io.restassured.config.MatcherConfig.ErrorDescriptionType.HAMCREST;
import static io.restassured.config.RestAssuredConfig.config;
import static org.hamcrest.Matchers.hasItem;
// default REST_ASSURED prints the whole extracted collection:
// JSON path bids.bidderId doesn't match.
// Expected: a collection containing "BID-99"
// Actual: <[BID-88, BID-91]>
given()
.config(config().matcherConfig(
MatcherConfig.matcherConfig().errorDescriptionType(HAMCREST)))
.when().get("/lots/LOT-4417")
.then().body("bids.bidderId", hasItem("BID-99"));
// with HAMCREST the matcher describes itself:
// Actual: mismatches were: [was "BID-88", was "BID-91"]go deeper
Know that a failed body expectation prints a path line, an Expected half and an Actual half, and that the Actual half's format is configurable rather than fixed.
Explain that MatcherConfig holds one setting with two constants, that REST_ASSURED is the default, and that only the Actual half changes between them.
Argue the operational case: for collection and composed matchers the Hamcrest style carries a per-element breakdown that turns an unreadable CI failure into a diagnosable one, and the setting belongs in shared configuration rather than in one test.
Treat failure-message quality as a suite-level property worth deciding once. Weigh whether the extra breakdown reduces reruns enough to justify a format change across every existing test's output.
When a REST Assured body expectation fails, the `AssertionError` it raises carries a message assembled from three pieces: a line naming the path, an `Expected:` half and an `Actual:` half. `MatcherConfig.errorDescriptionType` chooses who writes the third piece. ## Where the setting lives `io.restassured.config.MatcherConfig` is one of the eighteen config objects held by `RestAssuredConfig`. It carries a single setting and a single enum: - `errorDescriptionType(ErrorDescriptionType)` returns a new, user-configured `MatcherConfig`. - `ErrorDescriptionType` has exactly two constants: `REST_ASSURED` and `HAMCREST`. - The no-argument constructor uses `REST_ASSURED`, so that is the default you get without configuring anything. - The static factory is `MatcherConfig.matcherConfig()`, and the setter on the aggregate is `RestAssuredConfig.matcherConfig(...)`. Apply it per request with `given().config(...)`, or on a specification, exactly like any other config object. ## What stays the same either way Both styles produce the same leading line, built from the path engine's own name and your path — `JSON path <path> doesn't match.` for JSON and `XML path <path> doesn't match.` for XML. A whole-body expectation with no path instead leads with `Response body doesn't match expectation.` Both also derive the `Expected:` half from the matcher's description, because a Hamcrest matcher's `toString()` is its `describeTo` output. So the expectation half never changes. ## What changes: who describes the actual value Under `REST_ASSURED`, the library formats the extracted value itself, then strips the surrounding quotation marks if the rendered form is a quoted string. An array is joined with commas first. Against a cattle-auction lot whose `breed` came back as `Hereford`: ```text JSON path breed doesn't match. Expected: Angus Actual: Hereford ``` Under `HAMCREST`, REST Assured hands the actual value to `matcher.describeMismatch(...)` and prints what the matcher writes. The same failure becomes: ```text JSON path breed doesn't match. Expected: "Angus" Actual: was "Hereford" ``` Quotes survive, a blank line appears before `Expected:`, and the `was` prefix is the default mismatch text every Hamcrest matcher inherits. ## Why the difference is worth anything On a scalar the two are near-equivalent and the default reads more cleanly. The difference earns its keep on matchers that have something to say about *why* they failed. Take a lot with two bids and the expectation `body("bids.bidderId", hasItem("BID-99"))`: - `REST_ASSURED` prints the whole extracted collection as the actual value, leaving you to scan it. - `HAMCREST` prints the collection matcher's own breakdown, listing a mismatch entry per element. On a two-element list that is a small win. On a list of forty bids, or a composed matcher several layers deep, it is the difference between reading the failure and rerunning the test with logging turned on. ## What the two styles look like side by side | | `REST_ASSURED` (default) | `HAMCREST` | |---|---|---| | Leading line | `JSON path breed doesn't match.` | identical | | `Expected:` half | the matcher's description | the matcher's description | | `Actual:` half | the extracted value, rendered by REST Assured | whatever `describeMismatch` writes | | String quoting | surrounding quotes stripped | quotes kept | | Collection failure | the whole collection dumped | a per-element breakdown | The stripped quotes are the giveaway when you are reading an unfamiliar CI log and want to know which style a suite is running under. A bare `Actual: Hereford` is the default; `Actual: was "Hereford"` means somebody set the Hamcrest style. ## Choosing a setting - Leave it at `REST_ASSURED` for suites dominated by scalar field checks; the stripped-quote output is shorter and easier to skim in a CI log. - Switch to `HAMCREST` where expectations lean on collection and composed matchers, because those are the ones whose own mismatch text carries information the raw value does not. - Set it once, globally or on a shared configuration, rather than per test — a suite whose failure format varies by file is harder to read, not easier. - Remember it changes formatting only. It does not change which expectations pass, which fail, or what is thrown. - Do not confuse it with the logging controls; it rewrites the assertion message, not the request or response dump. ## The trap in an interview The name suggests it picks *which library performs the assertion*, and it does not. Hamcrest performs the match in both cases — REST Assured has no matching engine of its own for values. The setting picks only which side renders the mismatch text once the match has already failed. Saying that clearly is what the question is testing.
- Does errorDescriptionType change which assertions pass or fail?No. Matching is done by Hamcrest either way and the outcome is identical; only the text of the `Actual:` half of the failure message changes. The leading path line and the `Expected:` half, which comes from the matcher's own description, are the same under both settings.
- Where would switching to HAMCREST actually pay off?On expectations built from collection or composed matchers. Those matchers implement a mismatch description that explains which element or which clause failed, and the default style discards it in favour of dumping the raw extracted value. For scalar equality checks the default is shorter and reads better.
saying these in an interview costs you the question
- Thinks the setting chooses which library performs the match
- Believes it can change whether an expectation passes
- Assumes it also reformats the request and response logs
- Says the enum has more than two constants
- Claims HAMCREST is the default because Hamcrest does the matching