what is the usage of pathParam instead of full path in restAssured - java

According to this question I understand that pathParam is parameter for path in query.
But I don't understand what is the usage of that instead of writing the full path in get query like this if we have only one path anyway?
given().
baseUri("https://postman-echo.com")
.pathParam("userId", "1")
.when()
.get("/api/users/{userId}")
.then()
.log().ifError()
.assertThat()
.statusCode(200)

You could have your spec preserved and reuse parameter in different apis like:
public static void main(String[] args) {
RequestSpecification spec = given().
baseUri("https://httpbin.org/anything")
.pathParam("param", "123");
spec
.get("/api1/{param}")
.then()
.log().body();
spec
.get("/api2/{param}")
.then()
.log().body();
}

Related

Restassured request with spec doesn't get response status logged

I want my Restassured request with spec get response status logged.
My request is
given()
.spec(requestSpec)
.when()
.get("/" + userId)
.then()
.spec(responseSpec)
.extract().as(User.class)
;
My spec is
public static ResponseSpecification responseSpec = new ResponseSpecBuilder()
.expectStatusCode(200)
.log(STATUS)
.log(BODY)
.expectBody(notNullValue())
.build();
}
But there is no response status in the log unless I add .log().status() to my request.
Pls tell me how can I fix this.
UPDATE
Following Ashish Patil advice I updated my request but without result
LogConfig logconfig = new LogConfig().enablePrettyPrinting(true);
RestAssured.config().logConfig(logconfig);
given()
.spec(requestSpec)
.when()
.get("/" + userId)
.then()
.spec(responseSpec)
.extract().as(User.class)
;
Question didn't specify if you have set LogConfig before declaring your responseSpec. So you might need to declare LogConfig first to use log method as mentioned in doc :
LogConfig logconfig = new LogConfig().enablePrettyPrinting(true);
RestAssured.config().logConfig(logconfig);
And afterwords you can declare your responseSpec as per your question.
Actually, it's a bug. ResponseSpecification only supports one LogDetail at a time. For example:
...
.log(STATUS)
.log(BODY)
...
--> it will log BODY, not STATUS, because it is a variable declared
private LogDetail responseLogDetail, the latter value will override the previous value.
ResponseSpecificationImpl logDetail(LogDetail logDetail) {
this.responseLogDetail = logDetail
this
}

What is the difference between given() and with() in Rest Assured?

RequestSpecification request1 = RestAssured.given();
// Setting Base URI
request1.baseUri("https://restful-booker.herokuapp.com");
// Setting Base Path
request1.basePath("/booking");
// Creating request specification using with()
RequestSpecification request2 = RestAssured.with();
// Setting Base URI
request2.baseUri("https://restful-booker.herokuapp.com");
// Setting Base Path
request2.basePath("/ping");
As here we are using both what is the difference amongst two?
Methods: "and", "with", "when", "given", "that" and "request" are synctatic sugar for RequestSpecification and you don't need them to create RequestSpecification object.
The package com.jayway.restassured indicates that with() and given() do the same thing.
public static RequestSpecification with() {
return given();
}

Add AWS Signature Header to all rest assured requests

I'm trying to call an get api which is hosted in aws api gateway via rest-assured
I'm able to sign the request and make a call. But to sign the request, I need to pass the full url to AWS to generate the Authorization Header.
For Ex. If I'm going to access an an endpoint
https://my-aws-api.com/basepath/v1/request/123
I need to sign the request via AWSSigner which needs the full endpoint to do so.
My current approach
String baseURI="https://my-aws-api.com";
String basePath="basepath/v1";
String requestPath="request/123";
String endpoint=baseURI+"/"+basePath+"/"+requestPath;
Map<String,String> signedHeaders= aws4sign(endpoint,defaultHeaders);
given()
.log().ifValidationFails()
.headers(signedHeaders)
.when()
.get(endpoint)
.then()
.log().ifValidationFails()
.statusCode(200);
If I do that , then I cant use RestAssured's baseURI, basePath and path params
I want to access it like
RestAssured.baseURI="https://my-aws-api.com";
RestAssured.basePath="basepath/v1";
given()
.log().ifValidationFails()
.pathParam("reqID", "123")
.when()
.get("request/{reqID}")
.then()
.log().ifValidationFails()
.statusCode(200);
AwsSigner
public static Map<String, String> aws4Sign(String endpoint, Map<String, String> headers) throws URISyntaxException {
String serviceName = "execute-api";
AWS4Signer aws4Signer = new AWS4Signer();
aws4Signer.setRegionName(EU_WEST_1.getName());
aws4Signer.setServiceName(serviceName);
DefaultRequest defaultRequest = new DefaultRequest(serviceName);
URI uri = new URI(endpoint);
defaultRequest.setEndpoint(new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), "", "", ""));
defaultRequest.setHttpMethod(HttpMethodName.GET);
defaultRequest.setResourcePath(uri.getRawPath());
defaultRequest.setHeaders(headers);
aws4Signer.sign(defaultRequest, DefaultAWSCredentialsProviderChain.getInstance().getCredentials());
return defaultRequest.getHeaders();
}
So My question is there any way, I can intercept the RestAssured's request before it makes the call, so that I can get the fully generated end point and add the aws signed header to the call.
I am not familiar with this library but from briefly reading its documentation and Javadoc, you should be able to use a RequestFilter to inspect and alter a request before it is sent out.
Take a look at the Filter section of the user guide.
Thanks to #Ashaman.
The Filter Section is what I'm looking for
You can get the uri and other headers that were passed with requests from RequestSpec and then send it to the function to sign them and remove the old headers and put the new headers. Then forward the request
#BeforeAll
public void init() {
RestAssured.baseURI = "https://my-aws-api.com";
RestAssured.filters((requestSpec, responseSpec, ctx) -> {
Map<String, String> headers = requestSpec.getHeaders()
.asList()
.stream()
.collect(Collectors.toMap(Header::getName, Header::getValue));
Map<String, String> signedHeaders = aws4sign(requestSpec.getURI(), headers);
requestSpec.removeHeaders();
requestSpec.headers(signedHeaders);
return ctx.next(requestSpec, responseSpec);
});
}
And for the tests I can use the features of Rest Assured normally
given()
.log().ifValidationFails()
.pathParam("reqID", "123")
.when()
.get("request/{reqID}")
.then()
.log().ifValidationFails()
.statusCode(200);

REST ASSURED TEST creating my own given() method

I have more than two similar REST ASSURED rests e.g.
#Test
public void makeSureThatGoogleIsUp() {
given().auth().oauth2(getToken()).contentType("application/json")
.when()
.get("http://www.google.com")
.then()
.statusCode(200);
}
#Test
public void makeSureThatGoogleIsUp() {
given().auth().oauth2(getToken()).contentType("application/json")
.when()
.get("https://stackoverflow.com")
.then()
.statusCode(200);
}
And I would've like to create method called given() to make method less complex and readable.
private [something] given(){
return given().auth().oauth2(getToken()).contentType("application/json")
}
making my methods use my given instead of rest assured one:
#Test
public void makeSureThatGoogleIsUp() {
given()
.when()
.get("http://www.google.com")
.then()
.statusCode(200);
}
#Test
public void makeSureThatGoogleIsUp() {
given()
.when()
.get("https://stackoverflow.com")
.then()
.statusCode(200);
}
something like here: but I dont really know what kind of return type this method could have or if its even possible.
Sorry, question can be trival, but seriously I'm stuck here.
Any helps? Thanks! :)
It returns a RequestSpecification object: http://static.javadoc.io/com.jayway.restassured/rest-assured/2.4.1/com/jayway/restassured/specification/RequestSpecification.html
Also a side note if you're creating your own given() -- it might be better to name the method something else as someone else using it might assume it's the jayway version and confuse themselves when they get errors.

Asserting Rest Assured response with Json Unit

I'm currently using rest assured and Json-unit to assert a local json file against the requested rest assured response.
I currently have a before class method with my base uri.
I don't know how to make this assertion. I'm struggling with the json-unit documentation. Do I need to input a file first?
#Test
public void ApiaryTest1() throws Exception {
when()
.get("/test")
.then()
.statusCode(200);
// compares two JSON documents
assertJsonEquals("expected/test.json", "http://apiary/test");
}
You need to:
Read in the resource with the JsonUnit API
Extract the response from rest assured to a variable
Assert you are already doing
Example:
Response response = when().get("<url>");
response
.then()
.statusCode(200);
// compares two JSON documents
assertJsonEquals(resource("resource-inside-resources-folder.json"), response.asString());
For Restassured Kotlin DSL:
When {
get("http://nowjidev1vm01.ath.bskyb.com/calskyplussearch/health")
} Then {
statusCode(200)
} Extract {
assertJsonEquals(expectedBody, response().asString())
}
It is easier than you think. Rest Assures is passing the entire body as string in case of a "body matcher" is specified. Therefore you can just use the jsonEquals matcher of json unit directly:
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
public class RestAssuredWithJsonUnit {
#Test
public void test() throws Exception {
given().when().get("/api/service/v1").
then().
statusCode(200).
body(jsonEquals(resource("resource-on-classpath.json")));
}
public static String resource(String resourceName) throws IOException {
Objects.requireNonNull(resourceName, "'null' passed instead of resource name");
return IOUtils.resourceToString(resourceName, UTF_8);
}
Please note the implementation of the "resource" method. The one provided in ResourceUtils is using the system classloader, which did not found my resoulces unfortunately. IOUtils from commons-io does the job well!

Categories

Resources