Given the following JSON:
{
"priceOne": 1034,
"priceTwo": null,
"priceThree": 7282,
}
...and the following Rest Assured method to get the priceTwo
value and set to a specific value:
public void getPrice() {
setPriceService();
Response response =
given().
spec(priceServiceRequestSpec)
when().
get("api/v1/prices/102934").
then().extract().response();
if (StringUtils.isNotEmpty(response.path("priceTwo").toString())) {
vehicle.setPrice(response.path("priceTwo").toString());
return true;
} else {
vehicle.setPrice("2000");
}
}
...I am getting a NullPointerException when I expect the
StringUtils.isNotEmpty
to handle this. I expect this is down to the way I am using the response.path
as a paramater. What is a better way of achieving this?
-
If you are receiving this JSON object, you should never have an NPE. Are you sure "priceTwo" exists? If it doesn't, you will get the NPE on the .toString(), no on StringUtils.isNotEmpty().João Farias– João Farias2021年04月18日 08:19:03 +00:00Commented Apr 18, 2021 at 8:19
-
@JoãoFarias thanks, I think this makes sense. Problem is, I never know which price will be null, so I wanted a better way of doing a null check without lots of boilerplate try/catch NPE code. Any of the prices can be null (not a string "null") and I need to set a value IF they are nullSteerpike– Steerpike2021年04月18日 17:12:10 +00:00Commented Apr 18, 2021 at 17:12
-
I think this is perhaps the right approach: jvt.me/posts/2019/04/23/rest-assured-verify-field-not-setSteerpike– Steerpike2021年04月18日 17:41:46 +00:00Commented Apr 18, 2021 at 17:41
3 Answers 3
String response =RestAssured.get("https://praveendvd.free.beeceptor.com/test").
then().extract().response().asString();
JSONObject jsonObj = new JSONObject(response);
int val = (jsonObj.isNull("priceTwo")) ? 2:jsonObj.get("priceTwo");
vehicle.setPrice(val);
you can directly pass without creating a variable also:
vehicle.setPrice((jsonObj.isNull("priceTwo")) ? 2:jsonObj.get("priceTwo"));
use JsonObject has method and ternary operator java
-
thanks for the answer - this looks the neatest solution yet the
jsonObj.has
always evaluates to true, becausepriceTwo
key always exists, regardless of whether value is null, so the l/h side of?
always gets run with the result: org.json.JSONObject$Null cannot be cast to java.lang.Integer java.lang.ClassCastException: org.json.JSONObject$Null cannot be cast to java.lang.IntegerSteerpike– Steerpike2021年04月20日 10:42:52 +00:00Commented Apr 20, 2021 at 10:42 -
@Steerpike use jsonObj.isNull("species") then , i thought you want to validate whether key exists or notPDHide– PDHide2021年04月20日 11:00:07 +00:00Commented Apr 20, 2021 at 11:00
-
apologies, I probably wasn't clear. I want to perform conditional logic IF a value is null. So, I want to send a new Update RQ if any of the key values are null e.g. if
"priceTwo": null
Steerpike– Steerpike2021年04月20日 11:03:36 +00:00Commented Apr 20, 2021 at 11:03 -
@Steerpike is updated answerPDHide– PDHide2021年04月20日 11:20:49 +00:00Commented Apr 20, 2021 at 11:20
Response response =RestAssured.get("https://praveendvd.free.beeceptor.com/test").
then().extract();
if (StringUtils.isNotEmpty(response.path("priceTwo").toString())) {
vehicle.setPrice(response.path("priceTwo").toString());
return true;
} else {
vehicle.setPrice("2000");
}
You should creating a variable and also most probablity, you have a type casting problem that Response type to convert String for condition.
Since the path returns a reference type you can just use the construction like this:
if (response.path("priceTwo") instanceof Number) {
vehicle.setPrice(response.path("priceTwo").toString());
return true;
} else {
vehicle.setPrice("2000");
}
Below is the test:
public class Test {
public static void main(String[] args) {
Response response = RestAssured
.get("https://60269516186b4a0017780505.mockapi.io/rest_assured_nulls");
handleJson(response, "[0].priceOne");
handleJson(response, "[0].priceTwo");
handleJson(response, "asdfe");
}
private static void handleJson(Response response, String path){
if (response.path(path) instanceof Number) {
System.out.println("Valid number: " + response.path(path).toString());
} else {
System.out.println("Invalid number so setting default value");
}
}
}
which outputs:
Valid number: 1034
Invalid number so setting default value
Invalid number so setting default value
for my test endpoint
-
if response doesn't have priceTwo it will throw null point , that was the question i guessPDHide– PDHide2021年04月19日 17:34:01 +00:00Commented Apr 19, 2021 at 17:34
-
No, it will not.
null instanceof Number
will returnfalse
Alexey R.– Alexey R.2021年04月19日 17:47:14 +00:00Commented Apr 19, 2021 at 17:47 -
response.path("priceTwo") will through the errorPDHide– PDHide2021年04月19日 18:35:54 +00:00Commented Apr 19, 2021 at 18:35
-
response.path("asdasd") try this it will throw nullpointPDHide– PDHide2021年04月19日 18:39:21 +00:00Commented Apr 19, 2021 at 18:39
-
Not sure why we're talking about
response.path("asdasd")
. OP's issue is that"priceTwo": null
causes.toString()
be invoked against null reference because the value of the field isnull
. I'll check your examples as soon as get to my desktop.Alexey R.– Alexey R.2021年04月19日 19:00:06 +00:00Commented Apr 19, 2021 at 19:00