Search code examples
scalagatlingscala-gatling

Gatling: transform findAll to sorted list


I'm new to scala and Gatling. I'm trying to transform the result of findAll into a sorted list and then return a String representation of the sorted list. I can't seem to do this with the following code:

http(requestTitle)
  .post(serverUrl)
  .body(ElFileBody(sendMessageFile))
  .header("correlation-id", correlationId)
  .check(status.is(200),
    jsonPath("$.data.sendMessage.targetedRecipients").findAll.transform(recipients => {
      println("recipients class: " + recipients.getClass)
      var mutable = scala.collection.mutable.ListBuffer(recipients: _*)
      var sortedRecipients = mutable.sortWith(_ < _)
      println("users sorted "+ usersSorted)
      usersSorted.mkString(",")
  }).is(expectedMessageRecipients))

Recipients is of type scala.collection.immutable.Vector. I thought I would be able to convert the immutable collection into a mutable collection using scala.collection.mutable.ListBuffer. Any help would be appreciated, thanks.


Solution

  • I don't think your problem is immutability, it's JSON parsing vs Gatling's .find and .findAll methods.

    I'm going to make a guess that your response looks something like...

    {"data":{"sendMessage":{"targetedRecipients":[1,4,2,3]}}}
    

    in which case Gatling's .findAll method will return a vector (it always does if it finds something), but it will only have one element which will be "[1,4,2,3]" - ie: a string representing json data, so sorting the collection of a single element naturally achieves nothing. To get .findAll to behave like you seem to be expecting, you would need a response something like...

    {"data":
     {"sendMessage":
      {"targetedRecipients":
        [{"recipientId":1},
         {"recipientId":4},
         {"recipientId":2},
         {"recipientId":3}]
     }}}
    

    which you could use .jsonPath("$..recipientId").findAllto turn into a Vector[String] of the Ids.

    So assuming you are indeed just getting a single string representation of an array of values, you could use a straight transform to generate an array and sort (as you tried in your example)

    Here's a working version

    val data = """{"data":{"sendMessage":{"targetedRecipients":[1,4,2,3]}}}"""
    
    def sortedArray : ScenarioBuilder = scenario("sorting an array")
    .exec(http("test call")
    .post("http://httpbin.org/anything")
    .body(StringBody(data)).asJson
    .check(
      status.is(200),
      jsonPath("$.json.data.sendMessage.targetedRecipients")
        .find
        .transform(_
          .drop(1)
          .dropRight(1)
          .split(",")
          .toVector
          .sortWith(_<_)
        )
        .saveAs("received")
    ))
    .exec(session => {
      println(s"received: ${session("received").as[Vector[String]]}")
      session
    })