Q1 of 40 · REST Assured
How does RequestSpecBuilder reduce duplication in REST Assured tests?
Short answer
Short answer: RequestSpecBuilder lets you define a reusable base configuration — base URI, auth headers, content type, logging — once, then share it across all tests. Without it, every test repeats the same boilerplate setup, and a base URL change means editing every file.
Detail
REST Assured's default style puts all configuration inline inside a given().when().then() chain, which leads to repeated setup across test classes:
given()
.baseUri("https://api.example.com")
.header("Authorization", "Bearer " + token)
.contentType(ContentType.JSON)
.when().get("/users/1")
.then().statusCode(200);
RequestSpecBuilder extracts that repeated preamble into a reusable spec:
RequestSpecification baseSpec = new RequestSpecBuilder()
.setBaseUri("https://api.example.com")
.addHeader("Authorization", "Bearer " + token)
.setContentType(ContentType.JSON)
.log(LogDetail.ALL)
.build();
Once built, you pass it to given(baseSpec) in every test. If the base URL or auth scheme changes, you update one place.
Pairing with ResponseSpecBuilder: similarly, define expected response invariants — status code ranges, content-type assertions, max response time — and pass them to .then(baseResponseSpec). The combination produces tests that are short, declarative, and focused on the specific assertion rather than scaffolding.
Initialisation pattern: create the specs in a @BeforeAll method or a BaseTest superclass so they're built once per suite, not once per test method.
// EXAMPLE
BaseApiTest.java
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.filter.log.LogDetail;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import org.junit.jupiter.api.BeforeAll;
import static org.hamcrest.Matchers.*;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public abstract class BaseApiTest {
protected static RequestSpecification reqSpec;
protected static ResponseSpecification resSpec;
@BeforeAll
static void setupSpecs() {
reqSpec = new RequestSpecBuilder()
.setBaseUri(System.getenv("API_BASE_URL"))
.addHeader("Authorization", "Bearer " + getToken())
.setContentType(ContentType.JSON)
.log(LogDetail.ALL)
.build();
resSpec = new ResponseSpecBuilder()
.expectStatusCode(anyOf(is(200), is(201)))
.expectContentType(ContentType.JSON)
.expectResponseTime(lessThan(2000L), MILLISECONDS)
.build();
}
}
// UserApiTest — no boilerplate, focused assertions only
class UserApiTest extends BaseApiTest {
@Test
void getUser_returnsCorrectId() {
given(reqSpec).pathParam("id", 1)
.when().get("/users/{id}")
.then().spec(resSpec)
.body("id", equalTo(1))
.body("name", not(emptyString()));
}
}