-
Notifications
You must be signed in to change notification settings - Fork 0
JPostman Tutorial Part 3: Access Token and Chained Requests
Video tutorial: https://www.youtube.com/watch?v=u3Z9yjglmTs
In this tutorial, we go deeper into JPostman and review important features for real API test automation.
You will learn how JPostman handles immutable Request objects, how to resolve Postman environment placeholders, how to validate API responses with assertions, and how to chain REST API requests by passing an access token from one response into another request.
This tutorial continues from the previous setup where the Java Maven project already uses JPostman and the RestAssured executor.
By the end of this tutorial, you will know how to:
- Understand why the JPostman
Requestobject is immutable. - Build a resolved request using Postman environment values.
- Compare unresolved and resolved requests.
- Customize request URL, headers, auth, and body values with the request builder.
- Store API execution results in an
ApiResponse. - Assert the expected HTTP status code.
- Use a Postman collection reference for cleaner code.
- Rename variables for better readability.
- Debug missing authorization values.
- Extract an
accessTokenfrom one response. - Use the token in a second request.
- Create a chained request flow.
Before starting this tutorial, make sure you completed the previous tutorials:
- Part 1: Java Maven project setup with
jpostman-core. - Part 2: Execute REST API requests using
jpostman-restassured.
You should already have:
- A Maven test project.
- Exported Postman collection JSON file.
- Exported Postman environment JSON file.
- JPostman dependencies configured.
- A TestNG test class.
- RestAssured executor working.
https://www.youtube.com/watch?v=UxFjeONEq60
https://www.youtube.com/watch?v=hwsDjBSxIRs
JPostman Request objects are immutable.
This means the original request loaded from the exported Postman collection cannot be changed directly.
When you load a request from the collection, it keeps the same structure and placeholder values that came from Postman.
Example unresolved values may look like this:
{{base_url}}
{{username}}
{{password}}
{{accessToken}}
To apply environment values or custom changes, you must create a new resolved request using the request builder.
JPostman uses the builder to resolve placeholders from the Postman environment.
Example:
Request resolvedRequest = req.builder().build(env);This creates a new Request object with environment values applied.
The original request remains unchanged.
To inspect the difference between the original request and the resolved request, print both:
req.print();
Request resolvedRequest = req.builder().build(env);
resolvedRequest.print();When you run the test, the console shows that:
- The original request still contains unresolved placeholders.
- The resolved request replaces placeholders with values from the environment JSON file.
This helps confirm that JPostman does not mutate the original collection request.
The request builder can also manually customize request values before execution.
Common builder sections include:
url()
headers()
auth()
body()Example:
Request resolvedRequest = req.builder()
.url()
.add("q", "hello+world")
.map("base_url", "https://example.com")
.end()
.body()
.set("username", "sam")
.add("age", 21)
.end(env.getParams())
.build();This example shows how to:
- Add a URL query parameter.
- Replace the
{{base_url}}placeholder. - Replace an existing request body field.
- Add a new request body field.
- Resolve remaining body placeholders from the environment.
- Build a new resolved
Request.
After execution, the resolved request contains the updated URL and body values.
A TestNG test can pass even when the API returns an error status code unless you add assertions.
For example, an API may return:
405 Method Not Allowed
The test runner may still mark the test as passed if no assertion fails.
To properly validate the API result, store the execution result and assert the expected status code.
Import ApiResponse:
import io.jpostman.ApiResponse;Add a static import for TestNG assertEquals:
import static org.testng.Assert.assertEquals;Execute the request and store the response:
ApiResponse res = RestAssuredExecutor.execute(resolvedRequest);Assert the response status code:
assertEquals(res.statusCode(), 200, "Body Result: " + res.pretty() + "
");Now the test fails correctly when the API does not return the expected status code.
The assertion message includes the server response body for debugging.
After confirming the assertion works, remove temporary hardcoded request customizations.
The cleaned-up request flow should:
- Get the request from the collection.
- Resolve it with the environment.
- Execute it.
- Assert the response status code.
Example:
Request req = cxt.getCollection()
.getRequest("Login user and get tokens")
.builder()
.build(env);
ApiResponse res = RestAssuredExecutor.execute(req);
assertEquals(res.statusCode(), 200, "Body Result: " + res.pretty() + "
");Before selecting more requests, create a local reference to the Postman collection.
Import the JPostman Collection class:
import io.jpostman.Collection;Create a local variable:
Collection col = cxt.getCollection();This makes the code cleaner when calling multiple requests:
Request reqToken = col.getRequest("Login user and get tokens")
.builder()
.build(env);For readability, rename variables based on the request purpose.
Example:
Request reqToken
ApiResponse resTokenThese names make it clear that the request and response are related to the login or token API call.
When adding a second request, use names like:
Request reqUser
ApiResponse resUserThis keeps chained request code easier to read and maintain.
To view available requests from the loaded Postman collection, print the collection:
col.print();Run the test and review the console output.
For this tutorial, the second API request is:
Get current auth user
Reuse the same request execution pattern for the second request.
Example:
Request reqUser = col.getRequest("Get current auth user")
.builder()
.build(env);
ApiResponse resUser = RestAssuredExecutor.execute(reqUser);
assertEquals(resUser.statusCode(), 200, "Body Result: " + resUser.pretty() + "
");At this stage, the second request may fail with:
401 Access Token is required
This means the request is missing an authorization token.
To debug the authorization issue, print the unresolved and resolved versions of the second request.
Example:
col.getRequest("Get current auth user").print();
col.getRequest("Get current auth user")
.builder()
.build(env)
.print();The console output shows that the unresolved request expects an accessToken, but the resolved request still has an empty value.
This means the environment does not yet contain the access token needed for the second API call.
Print the token response:
resToken.print();The login request returns an accessToken in the response body.
This token can be used in the next request.
Instead of relying on a static environment value, extract the token from the first response and pass it into the second request.
Use the token response path:
resToken.path("accessToken")Then configure the second request authorization with OAuth2:
ApiResponse resUser = RestAssuredExecutor
.apply(reqUser)
.auth()
.oauth2(resToken.path("accessToken"))
.response();This creates a chained request flow:
- Execute the login request.
- Extract
accessTokenfrom the login response. - Use that token in the next request.
- Execute the authenticated user request.
Example test flow:
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import io.jpostman.ApiResponse;
import io.jpostman.Collection;
import io.jpostman.Environment;
import io.jpostman.JPostman;
import io.jpostman.JPostman.Context;
import io.jpostman.Request;
import io.jpostman.restassured.RestAssuredExecutor;
public class DemoTest {
@Test
public void test1() throws Exception {
Context cxt = JPostman
.fromResources()
.collection("DummyJSON.postman_collection.json")
.environment("DummyJSON.postman_environment.json")
.build();
Environment env = cxt.getEnvironment();
Collection col = cxt.getCollection();
Request reqToken = col.getRequest("Login user and get tokens")
.builder()
.build(env);
ApiResponse resToken = RestAssuredExecutor.execute(reqToken);
assertEquals(resToken.statusCode(), 200, "Body Result: " + resToken.pretty() + "
");
Request reqUser = col.getRequest("Get current auth user")
.builder()
.build(env);
ApiResponse resUser = RestAssuredExecutor
.apply(reqUser)
.auth()
.oauth2(resToken.path("accessToken"))
.response();
assertEquals(resUser.statusCode(), 200, "Body Result: " + resUser.pretty() + "
");
}
}Update the collection and environment file names if your exported files use different names.
This test performs a simple chained API flow:
- Loads the Postman collection.
- Loads the Postman environment.
- Gets the login request from the collection.
- Resolves environment placeholders.
- Executes the login request.
- Validates that login returns status code
200. - Extracts the
accessTokenfrom the login response. - Gets the authenticated user request.
- Applies OAuth2 authorization using the extracted token.
- Executes the second request.
- Validates that the authenticated request returns status code
200.
Chained requests are common in API test automation.
They are useful when one request depends on data returned from another request.
Common examples include:
- Login request returns an access token.
- Create request returns an ID used by a get, update, or delete request.
- Search request returns an object used in a follow-up request.
- Authentication request returns session data used by later requests.
JPostman makes this easier by letting you reuse Postman requests while still controlling dynamic values from Java.
In this tutorial, we reviewed how JPostman keeps collection requests immutable, how to create resolved requests with environment values, and how to validate API responses with TestNG assertions.
We also created a chained request flow by extracting an accessToken from a login response and passing it into a second authenticated request using OAuth2 authorization.
In the next tutorial, we will review best practices for organizing multiple requests in TestNG.
- Video tutorial: https://www.youtube.com/watch?v=u3Z9yjglmTs
- Part 1 video: https://www.youtube.com/watch?v=UxFjeONEq60
- Part 2 video: https://www.youtube.com/watch?v=hwsDjBSxIRs
- JPostman GitHub repository: https://github.com/JPostman/jpostman
- DummyJSON API: https://dummyjson.com