Welcome to the new Parasoft forums! We hope you will enjoy the site and try out some of the new features, like sharing an idea you may have for one of our products or following a category.

Building a dynamic JSON Request body with n objects in an array

beitliche
beitliche Posts: 3

Hello,

I have a use case that I'm trying to implement in SOATest and am running into a wall.

I have a Service1 that returns n number of Account objects. There are a varying amount of accounts that could be returned for a given request as that user may have more or less accounts than another.

I have a second service, Service2, that takes a structured request of n Account objects and AccountId is an integer that is required on all Accounts passed.

What I am attempting to do is extract AccountIds from the Service1 response and then build out a request to Service2 in a dynamic fashion. I have tried using a JSON Databank to extract the AccountIds from Service1 and then paramaterized that to the Service2 request but it just pastes ALL the AccountIds into a single AccountId field. Is there any way to dynamically create an array of objects using SOATest, in memory?

See below for samples.

Service1 Response:
{
"AccountSummaryList":[
{
"AccountId":"111111111",
"AccountType:"BLAHBLAH"
},
{
"AccountId":"22222",
"AccountType:"BLAHBLAH"
},
{.....}
]
}

Service2 Request:
{
"Accounts":[
{
"AccountId":111111,
"otherdetails":"blahblah"
},
{
"AccountId":222222,
"otherdetails":"blahblah"
}
]
}

Tagged:

Comments

  • melmath
    melmath Posts: 1

    I second this question!

  • Ramiro Martinez
    Ramiro Martinez Posts: 53 admin

    Hi Beitliche,

    There are possibly more elegant implementations, but off the top of my head I would use an XML data bank to extract all of the element values to a Writable data source.

    Modify the Xpath to grab all values not just a single one.

    Once written into a data source you can then use the
    context.getValues("writable_name","column_name") method to move the values to an arraylist and then simply loop the values while adding the tags. You would then have your xml body.

    This Example requires the use of a test suite variable. (Double click the test suite and navigate to then variable tab)
    Example script:
    import com.parasoft.api.*;

    public void compareASC(Object input, ScriptingContext context)
    {
            String fullString = "";
            ArrayList<String> list = context.getValues("data","values");
            for(int i = 0; i < list.size() ; i++)
            {
                  String a = list.get(i);
                  a = "<test>" + a + "</test>";
                  fullString += a;
           }
           context.setValue("x", fullString);
    }
    

    Now you can reference the variable "x" to get the values.

    In your messaging client, switch to "literal mode"(otherwise the background encoding will change the '<' & '>') and reference the variable with ${variable_name} .

    The scenario

  • benken_parasoft
    benken_parasoft Posts: 1,306 ✭✭✭
    edited July 2017

    Here is some general information.

    It is common for to take elements/objects/arrays from a response and then reuse them in a subsequent request. Typically, you would do the following:

    1. Extract the desired element/object/array that you want to reuse to a data bank column. In the data bank, click Modify to open the Modify Selected XPath settings dialog. Make sure "Entire element" is selected and not "Content only".
    2. In the subsequent request, replace the desired element/property/item with the data bank column. In the Form view, you would right-click the on the element you want to replace then click "Replace with Data Source Value", select Data Bank, choose your data bank column, then click Finish.

    What I mention applies to both JSON and XML. For JSON, you would be using a JSON Data Bank and the Form JSON view. For XML, you would be using an XML Data Bank and the Form Input view.

    Sometimes using the extraction as-is is desired. However, in some scenarios you want to transform the data in some way before reusing it. This could be accomplished using scripting (Extension Tool) or using XSL (XSLT Tool). Some simple transformations, like removing or appending values, can be applied by Data Bank itself by enabling the "Allow alteration" box under Options (collapsed by default).

    Ramiro's response is one such example where scripting can be used to transform extracted values.

  • beitliche
    beitliche Posts: 3

    Hello,

    Thank you for your responses.

    @benken_parasoft I have tried the above and am not seeing the intended outcome.

    Here is a sample of the response that I am extracting the AccountId values from:

    From this response I have the following data bank/xpath setup. As you can see it's set in "AccountId, ####" format. Which I would expect to be able to use.

    In the secondary request I am trying to build here is a sample of the form JSON (There will be other elements, I'm just trying to get this one working for now as a POC).

    I have tried setting the Replacement at the Accounts, and Item[0] level (as those are the only two that allow it. I cannot add a replacement at the AccountId level). I receive the following error when attempting this.

    Please advise if I am missing something but as far as I can tell SOATest does not natively support the use case for which I am trying. Short of coding up an extension to build this request I cannot see a path forward.

    Thanks!

  • benken_parasoft
    benken_parasoft Posts: 1,306 ✭✭✭
    edited July 2017

    The steps I described are for extracting the entire array and then replacing the entire array element. If you want to do that then you would extract the value of the AccountSummaryList array and then replace the Accounts array in the subsequent test.

    As mentioned, more steps or different steps would be required if you need to transform the contents of the array being extracted (change/add/remove values or rename things). As mentioned, this may have involve scripting or XSL. Ramiro gives one such example. Please note that if you follow Ramiro's example, he's not extracting the entire array but the contents to a Writable Data Source and using scripting to construct the desired result (which is a different approach than what I describe but also fine).

  • tsworld
    tsworld Posts: 14

    @Ramiro Martinez I am dealing with exact problem and following your solution.

    Where do I need to put the example script that you provided and if your script is Java then I get option to specify class and not script.

    Thanks in advance

  • jakubiak
    jakubiak Posts: 813 admin

    The script referenced by Ramiro was a groovy script.

  • tsworld
    tsworld Posts: 14

    Thanks @jakubiak for responding. I added code as groovy in Extension Tool. When I right click on script and Evaluate it does nothing, no console output even if I keep some println statements or garbage. Still if I run the test I see failure in Console:-

    Test 2: Extension Tool - failure
    Test failed

Tagged