skip to content

In REST Assured's ParamConfig, which parameter type defaults to REPLACE, and why can't you configure it?

level: seniorimportance: should knowfreq 30%

answer

  1. four kinds, one odd one out
  2. a placeholder is a single slot
  3. four getters, three setters
  4. mergeAllParameters over-promises

basics

~10 s

Path parameters. ParamConfig defaults query, form and request parameters to MERGE but path parameters to REPLACE, and it exposes four getters with only three setters - there is no path-parameter setter to call.

solid answer

~30 s

`ParamConfig` covers four parameter kinds and its defaults are `(MERGE, REPLACE, MERGE, MERGE)` for query, path, form and request parameters. Path parameters are the exception because a placeholder such as `/v1/ploughs/{ploughId}` is a single slot: there is no valid URL that carries two values for it, so merging has no correct rendering and the later value simply wins. That is also why the class exposes `queryParamsUpdateStrategy(...)`, `formParamsUpdateStrategy(...)` and `requestParamsUpdateStrategy(...)` but no path-parameter setter — `pathParamsUpdateStrategy()` is a getter only. The trap is the name of the shortcut: `mergeAllParameters()` still leaves path parameters on `REPLACE`. Only `replaceAllParameters()` gives you a uniform config.

code

java · 23 lines
java
import io.restassured.config.ParamConfig;

import static io.restassured.config.ParamConfig.UpdateStrategy.REPLACE;
import static io.restassured.config.ParamConfig.paramConfig;

class DispatchParamConfigRoster {

    void whatTheDefaultsAre() {
        ParamConfig defaults = paramConfig();
        defaults.queryParamsUpdateStrategy();    // MERGE
        defaults.formParamsUpdateStrategy();     // MERGE
        defaults.requestParamsUpdateStrategy();  // MERGE
        defaults.pathParamsUpdateStrategy();     // REPLACE, and there is no setter for it

        ParamConfig merged = paramConfig().mergeAllParameters();
        merged.pathParamsUpdateStrategy();       // still REPLACE

        ParamConfig replaced = paramConfig().replaceAllParameters();
        replaced.queryParamsUpdateStrategy();    // REPLACE

        paramConfig().queryParamsUpdateStrategy(REPLACE);  // one of the three setters
    }
}

go deeper

for a junior

Remember the shape rather than the API: repeating a query parameter adds a value, repeating a path parameter replaces one. That alone predicts most surprises when a shared setup and a test both set something.

for a middle

Explain the roster and the reason for the exception - a placeholder is one URL slot, so a merged rendering does not exist - and name UpdateStrategy's two constants.

for a senior

Diagnose the mixed case: in one shared specification the query parameter accumulates while the path parameter is overridden. Point out that mergeAllParameters does not touch path parameters despite its name.

for a principal

Take the wider lesson into review standards: read a configuration roster rather than inferring symmetric setters from a field list, and treat a fluent name that over-promises as a documentation defect to call out.

## The roster, in one table `ParamConfig` is one of the eighteen configuration objects `RestAssuredConfig` holds, and it answers a single question: when a parameter name is set twice, does the second call add a value or replace one? Its `UpdateStrategy` enum has exactly two constants, `MERGE` and `REPLACE`. The shipped defaults are not uniform: | parameter kind | default strategy | setter on `ParamConfig`? | |---|---|---| | query parameters | `MERGE` | `queryParamsUpdateStrategy(UpdateStrategy)` | | form parameters | `MERGE` | `formParamsUpdateStrategy(UpdateStrategy)` | | request parameters (the verb-driven kind) | `MERGE` | `requestParamsUpdateStrategy(UpdateStrategy)` | | path parameters | `REPLACE` | **none** | Four kinds, four getters — `queryParamsUpdateStrategy()`, `formParamsUpdateStrategy()`, `requestParamsUpdateStrategy()`, `pathParamsUpdateStrategy()` — and only three setters. The asymmetry is real, and it is exactly the kind of shape you cannot infer from a field list. ## Why path parameters replace The other three kinds describe things HTTP is happy to repeat. `?zone=north&zone=south` is a well-formed query string for a snowplough dispatch API, and a url-encoded body may carry a name twice. A path placeholder is not like that: `/v1/ploughs/{ploughId}` has exactly one slot, and there is no rendering of two values that produces a valid URL. Merging would mean either concatenating two values into one segment or failing at send time, so REST Assured takes the only sane option and lets the later value win. That also explains the missing setter. There is nothing to configure, because `MERGE` would have no correct implementation for a single-slot substitution. In the classic HTTP request implementation the named path-parameter map is updated with `REPLACE` passed directly rather than read from the config, so a `ParamConfig` carrying anything else for path parameters would not change what is sent; the getter exists so that the Spring-module configurations, which build their own parameter config from a `ParamConfig`, can carry the value across. ## `mergeAllParameters()` does not merge everything The single most quotable consequence: - `paramConfig()` — the no-argument default — is `(MERGE, REPLACE, MERGE, MERGE)` for query, path, form and request parameters respectively. - `mergeAllParameters()` returns the **same** four values. Despite the name, path parameters remain `REPLACE`. - `replaceAllParameters()` is the only method that produces a uniform config; it sets all four to `REPLACE`. - The four-argument public constructor lets you pass a path strategy, and the value you pass still will not change how the classic DSL substitutes a placeholder. - `isUserConfigured()` reports whether the instance came from the default constructor or from one of the fluent methods, which is what specification merging uses to decide whether your config or the incoming one wins. If an interviewer asks you to name a method whose name over-promises, this is a good answer. ## What it means for a shared dispatch specification Consider a suite where a shared `RequestSpecification` sets both a query parameter and a path parameter, and an individual test sets both again: 1. The query parameter accumulates — the dispatch service receives two values and the test fails for a reason that looks like an endpoint bug. 2. The path parameter does not accumulate — the test's value wins, quietly and correctly, with no configuration required. Two kinds of parameter, set the same way in the same file, behaving oppositely. Knowing which is which is the difference between a five-minute fix and an afternoon of bisecting a shared specification. It is also a good argument for the discipline that avoids the whole class of problem: let one layer own each parameter, and do not set the same name in two places. ## The general lesson The habit worth taking from this leaf is not the table; it is the reflex behind it. A configuration object with four fields does not necessarily have four setters, and a fluent method named `mergeAllParameters()` does not necessarily merge all parameters. Read the roster rather than inferring it, especially for a library where the fluent API is designed to read like English. An invented `pathParamsUpdateStrategy(REPLACE)` call compiles in your head and fails at the keyboard. ## What to say in an interview Give the defaults as a set — `MERGE` for query, form and request parameters, `REPLACE` for path parameters — then say why the odd one out is odd: a placeholder is a single slot, so there is no merged form to send. Finish with the two details that show you have actually read `ParamConfig`: there is no path-parameter setter, and `mergeAllParameters()` leaves path parameters on `REPLACE` anyway.

  • Why does mergeAllParameters() leave path parameters on REPLACE in REST Assured?
    Because there is no merged form of a path parameter to produce. A placeholder occupies one URL segment, so two values cannot both be rendered. The method sets the three kinds that HTTP allows to repeat and leaves the fourth at REPLACE; only `replaceAllParameters()` returns a config where all four agree.
  • How would you make a test override a query parameter a shared REST Assured specification already set?
    Either configure `queryParamsUpdateStrategy(REPLACE)` on that request, or stop setting the parameter in two places. The second is usually better: it removes the ambiguity for every future reader instead of relying on a configuration flag that changes multi-value filters elsewhere in the suite.

saying these in an interview costs you the question

  • Assumes all four parameter kinds default to MERGE
  • Invents a pathParamsUpdateStrategy setter that does not exist
  • Thinks mergeAllParameters makes path parameters merge
  • Cannot say why a placeholder cannot hold two values
  • Believes UpdateStrategy carries more than MERGE and REPLACE