So I am testing the controller of my application and I stumbled upon a problem.
This is the Json I use in my testcode:
String bike = "{" +
" \"bikeNumber\" : \"E2\"," +
" \"brand\" : \"Gazelle\"," +
" \"frameNumber\" : \"HA1234568\"," +
" \"retailPrice\" : 1200," +
" \"basePrice\" : 20.0," +
" \"electric\" : true" +
"}";
I want to test when the user doesn't fill in one of the values, it throws an exception. In other words I want to test the #NotNull, #NotBlank annotations.
I have done this for bikeNumber and frameNumber, these are string types and I can leave them open. The problem I get if I leave the basePrice open and run my test, I get an error saying:
java.lang.AssertionError: No value at JSON path "$.basePrice"
I know that it's a null value because I haven't filled it in, but that is part of the plan. So my question is, how do I leave a long, double or int value empty without getting a test error.
My full code block is here:
#Test
void whenPostRequestNoBasePrice_thenBadRequestResponse() throws Exception {
String bike = "{" +
" \"bikeNumber\" : \"E1\"," +
" \"brand\" : \"Gazelle\"," +
" \"frameNumber\" : \"HA1234568\"," +
" \"retailPrice\" : 1200," +
" \"basePrice\" : \"\" " +
" \"electric\" : true" +
"}";
mockMvc.perform(MockMvcRequestBuilders.post("/createbike")
.content(bike)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.basePrice", Is.is( "Base price is mandatory.")))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)).andReturn().getResponse().getContentAsString();
}
I tried multiple things, also with and without the comma: "basePrice" : "" ," +
Also I can't seem to find this anywhere on stackoverflow.
Related
I have a JSON payload saved as a String
String jsonBody = “{\n”
+ ” \“example\“: {\n”
+ ” \“example\“: [\n”
+ ” {\n”
+ ” \“example\“: 100,\n”
+ ” \“this_is_example_json_key\“: \“this_is_example_json_value\“,\n”
I created that by copying body from i.e Postman into
String jsonBody = "here I pasted the body";
Unfortunately I cannot have everything hardcoded there, so I have to change some values to variables. The JSON in postman looks like:
"this_is_example_json_key":"x"
And so on. Let's assume that:
String x = “this_is_example_json_value“;
If I just replace it like
+ ” \“this_is_example_json_key\“: \“ + x + \“,\n”
or something like that, the value in the body will be just this_is_example_json_value, where I need "this_is_example_json_value" (the "" marks are part of the value).
So the question is, how to set up those + / " in the String, so in the end in the value of the JSON I will end up with the value inside " ".
I've tried to play with the " / + but nothing of those were working. Variable must be passed with those " " because otherwise, the API is sending back an error.
Since java 15, if you want only use the string, you can also do in this way:
int this_is_example_json_value= 100;
String json = """
{
"this_is_example_json_key": %d
}
""".formatted(this_is_example_json_value);
Here the official jep.
Don't try to build up JSON using strings. Use a proper JSON parser.
import org.json.JSONException;
import org.json.JSONObject;
public class Eg {
public static void main(String[] args) throws JSONException {
String x = "this_is_example_json_value";
JSONObject example = new JSONObject();
example.put("this_is_example_json_key", x);
System.out.println(example.toString());
}
}
Which outputs:
{"this_is_example_json_key":"this_is_example_json_value"}
With no messing around wondering what needs to be escaped.
you can use an extra " \ " "
String x = "this_is_example_json_value";
String jsonBody = "{\n"
+ "\"example\": {\n"
+ " \"example\": [\n"
+ " {\n"
+ " \"example\": 100,\n"
+ "\"this_is_example_json_key\":" + "\"" + x + "\"" + "\n }"
+"\n ]\n }\n }";
in this case you will get a json string
{
"example": {
"example": [
{
"example": 100,
"this_is_example_json_key": "this_is_example_json_value"
}
]
}
}
This could be a duplicate question, but I couldn't find my solution anywhere. Hence, posting it.
I am trying to simply POST a request for a Student account Creation Scenario. I do have a JSON file which comprises all the "Keys:Values", required for Student account creation.
This is how the file student_Profile.json looks like:
{
"FirstName":"APi1-Stud-FN",
"MiddleInitial":"Q",
"LastName":"APi1-Stud-LN",
"UserAlternateEmail":"",
"SecretQuestionId":12,
"SecretQuestionAnswer":"Scot",
"UserName":"APi1-stud#xyz.com",
"VerifyUserName":"APi1-stud#xyz.com",
"Password":"A123456",
"VerifyPassword":"A123456",
"YKey":"123xyz",
"YId":6,
"Status":false,
"KeyCode":"",
"SsoUserName":"APi1-stud#xyz.com",
"SsoPassword":"",
"BirthYear":2001
}
So everything on Posting the request from "Rest Assured" point of view looks fine, it's just that I want to update a few values from the above JSON body using JAVA so that I can create a new Student profile every time I run my function and don't have to manually change the Body.
For Every POST Student Account Creation scenario, I need to update the value for
the following keys so that a new test student user account can be created:
First Name
Last Name and
Username // "VerifyUserName" and "SSO UserName" will remain same as user name
I modified the answer to get random values and pass them to json body. random value generation was taken from the accepted answer of this question.
public void testMethod() {
List<String> randomValueList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
String SALTCHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
StringBuilder salt = new StringBuilder();
Random rnd = new Random();
while (salt.length() < 18) { // length of the random string.
int index = (int) (rnd.nextFloat() * SALTCHARS.length());
salt.append(SALTCHARS.charAt(index));
}
randomValueList.add(salt.toString());
}
String jsonBody = "{\n" +
" \"FirstName\":\"" + randomValueList.remove(0) + "\",\n" +
" \"MiddleInitial\":\"Q\",\n" +
" \"LastName\":\"" + randomValueList.remove(0) + "\",\n" +
" \"UserAlternateEmail\":\"\",\n" +
" \"SecretQuestionId\":12,\n" +
" \"SecretQuestionAnswer\":\"Scot\",\n" +
" \"UserName\":\"" + randomValueList.remove(0) + " \",\n" +
" \"VerifyUserName\":\"APi1-stud#xyz.com\",\n" +
" \"Password\":\"A123456\",\n" +
" \"VerifyPassword\":\"A123456\",\n" +
" \"YKey\":\"123xyz\",\n" +
" \"YId\":6,\n" +
" \"Status\":false,\n" +
" \"KeyCode\":\"\",\n" +
" \"SsoUserName\":\"APi1-stud#xyz.com\",\n" +
" \"SsoPassword\":\"\",\n" +
" \"BirthYear\":2001\n" +
"}";
Response response = RestAssured
.given()
.body(jsonBody)
.when()
.post("api_url")
.then()
.extract()
.response();
// Do what you need to do with the response body
}
We can used pojo based approach to do certain things very easily . No matter how complex is the payload , serialization and dieselization is the best answer . I have created a framework template for api automation that can we used by putting required POJO's in path :
https://github.com/tanuj-vishnoi/pojo_api_automation
To create pojo, I also have ready to eat food for you :
https://github.com/tanuj-vishnoi/pojo_generator_using_jsonschema2pojo
for the above problem you can refer to the JsonPath lib https://github.com/json-path/JsonPath and use this code:
String mypayload = "{\n" +
" \"FirstName\":\"APi1-Stud-FN\",\n" +
" \"MiddleInitial\":\"Q\",\n" +
" \"LastName\":\"APi1-Stud-LN\"}";
Map map = JsonPath.parse(mypayload).read("$",Map.class);
System.out.println(list);
once the payload converted into map you can change only required values as per the requirement
To generate random strings you can refer to lib org.apache.commons.lang3.RandomStringUtils;
public static String generateUniqueString(int lenghtOfString){
return
RandomStringUtils.randomAlphabetic(lenghtOfString).toLowerCase();
}
I recommend to store payload in a separate file and load it at runtime.
I have a JSONObject that is similar to something like this:
{
"category":"abc"
"staus":""open"
"external":[
{"name":"123", "type":"OTHER"},
{"name":"678", "type":"ALPHA"},
{"name":"890", "type":"DELTA"}
]
}
If I want to use JSONAssert to check if the item {"name":"678"} exists and I don't know the item's order and the number of items in the "external" array, how should I do in Java?
It seems the ArrayValueMatcher should be the way to go but I just cannot get it works.
Please help
You could use JsonPath for this usecase :
JSONArray array = JsonPath.read(json, "$.external[?(#.name == '678')]");
Assertions.assertThat(array).hasSize(1);
Here is a complete example using JsonAssert:
#Test
public void foo() throws Exception {
String jsonString = "{\n" +
" \"category\":\"abc\",\n" +
" \"staus\":\"open\",\n" +
" \"external\":[\n" +
" {\"name\":\"123\", \"type\":\"OTHER\"},\n" +
" {\"name\":\"678\", \"type\":\"ALPHA\"},\n" +
" {\"name\":\"890\", \"type\":\"DELTA\"}\n" +
" ]\n" +
"}";
JsonAssert.with(jsonString).assertThat("$.external[*].name", hasItem(equalTo("678")));
}
I have a java virtual user script that is sending a payload request. I am trying to use values from a file to send via a loadrunner file parameter.
here is the payload:
private static final String PAYLOAD =
"<ips_cad_mdt>\n" +
" <SignOnRequest>\n" +
" <DestApplication>hhhh</DestApplication>\n" +
" <OrigApplication>hhh</OrigApplication>\n" +
" <SessionRef>3</SessionRef>\n" +
" <Aliasing>1234</Aliasing>\n" +
" </SignOnRequest>\n" +
"</ips_cad_mdt>";
I would like to use something like the following:
private static final String PAYLOAD =
"<ips_cad_mdt>\n" +
" <SignOnRequest>\n" +
" <DestApplication>hhh</DestApplication>\n" +
" <OrigApplication>hhh</OrigApplication>\n" +
" <SessionRef>3</SessionRef>\n" +
" <Aliasing>”+lr.eval_string(“{AliasId}”)+”</Aliasing>\n" +
" </SignOnRequest>\n" +
"</ips_cad_mdt>";
for some reason i cant see any output for this value. do i need to declare a variable: e.g. lr.save_string("AliasId", "{AliasId}");
an example of this would help loads. Many Thanks
There seems to be an error in the code completion in VuGen. The parameters should be reversed and without the {} in save_string.
lr.save_string("1234","myId");
lr.message(lr.eval_string("{myId}"));
In the documentation it is correct - https://admhelp.microfocus.com/lr/en/12.55/help/function_reference/FuncRef.htm#FuncRef/c_vuser/lrFr_lr_save_string.htm?Highlight=lr_save_string
I asked the responsible team to fix the code completion in VuGen so you will be able to see this change in one of the future releases.
I have constructed a JSON String this way , but cannot able to pass dynamic values to it
String input = "{\r\n" +
" \"Level\": 0,\r\n" +
" \"Name\": \"String\",\r\n" +
" \"msgName\": \"String\",\r\n" +
" \"ActualMessage\": \"String\",\r\n" +
" \"TimeStamp\": \"/Date(-62135596800000-0000)/\"\r\n" +
"}" ;
String message = "this is value want to pass to the ActualMessage attribute " ;
I need to pass dynamic value to the ActaulMessage atribute
Please tell me how ?
i have tried number of trial and errors but couldn't able to succeed.
Use string concatenation.
String message = "this is value want to pass to the ActualMessage attribute " ;
String input = "{\r\n" +
"\"Level\": 0,\r\n" +
"\"Name\": \"String\",\r\n" +
"\"msgName\": \"String\",\r\n" +
"\"ActualMessage\": \"" + message + "\",\r\n" +
"\"TimeStamp\": \"/Date(-62135596800000-0000)/\"\r\n" +
"}" ;
How about using String.format() for this? for example, to pass a "dynamic value" declare a place holder in the text:
String input = "insert %s in the string"; // here %s is the placeholder
input = String.format(input, "value"); // replace %s with actual value
Now input will contain the string "insert value in the string". In your example, change this line:
" \"msgName\": \"String\",\r\n"
Replace it with this:
" \"msgName\": \"%s\",\r\n"
Now you can perform the substitution:
input = String.format(input, message);
Notice that the first parameter in the format() method has a lot more of options, and that you can pass more than one argument to be replaced. Take a look at the documentation for the Formatter class.
if you want to manipulate Json please consider GSON. your problem can be addressed as follows.
String input = "{\r\n" +
" \"Level\": 0,\r\n" +
" \"Name\": \"String\",\r\n" +
" \"msgName\": \"MessageName\",\r\n" +
" \"ActualMessage\": \"%s\",\r\n" +
" \"TimeStamp\": \"/Date(-62135596800000-0000)/\"\r\n" +
"}" ;
String message = "this is value want to pass to the ActualMessage attribute " ;
String output=String.format(input,message);
//this will replace %s with the content of message variable.