2

I am getting some runtime values from a JSON response in my Karate based API Automation. I am storing them into an ArrayList like:

   * def ArrayList = Java.type('java.util.ArrayList')
   * def Collections = Java.type('java.util.Collections')
  ArrayList al = new ArrayList();
  * eval for(var i = 0; i < actualPrice.length; i++) expectedPrice.add(actualPrice[i])

When I printed the list, the output was :

[-150, -210, -100, -112.5]

Above output, When I applied to sort with the help of Collections.sort(al), It threw me the following error:

class java.lang.Integer cannot be cast to class java. lang.Double (java.lang.Integer and java.lang. Double is in module java.base of loader.

I need to use Asc/Desc sorting in the Karate feature file. Can someone please help me here?

Java Equivalent Code is:

    ArrayList al = new ArrayList();
    al.add(-150);
    al.add(-210);
    al.add(-100);
    al.add(-112.5);
    System.out.println(al);
    Collections.sort(al);
QualityMatters
  • 895
  • 11
  • 31

3 Answers3

3

You are adding both Integers and Doubles to the same List. When the sorting method attempts to compare an Integer to a Double it attempts to cast an Integer to a Double, which fails.

Don't use raw types. If you need to add double values to the List, use a List<Double>:

List<Double> al = new ArrayList<>();
al.add(-150.0);
al.add(-210.0);
al.add(-100.0);
al.add(-112.5);
System.out.println(al);
Collections.sort(al);

This way all the elements of your List will be of the same type, and Collections.sort() won't have trouble comparing them to each other.

Eran
  • 387,369
  • 54
  • 702
  • 768
1

Guess what we just added a karate.sort() API. Unfortunately this is not in 0.9.9.RC3 so if you can start trying to build from source, that will help us confirm this works as expected.

Here is the link to the docs on how it is supposed to work: https://github.com/intuit/karate/tree/develop#json-transforms

* def foo = [{a: { b: 3 }}, {a: { b: 1 }}, {a: { b: 2 }}]
* def fun = function(x){ return x.a.b }
* def bar = karate.sort(foo, fun)
* match bar == [{a: { b: 1 }}, {a: { b: 2 }}, {a: { b: 3 }}]   

In the meantime you can consider moving all the logic for sorting into a Java util that you call from Karate and just pass JSON in / out - that might be simpler than messing around with Java collections and all.

Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
1

Providing the answer to the above question which helped me:

Approach:

  1. First checked if the object added at run time is Integer type or not.

  2. If it is an Integer type, then converted it into Double.

  3. After converting, replaced that object with double values.

  4. Performed sorting.

    for(Object o :al) {
        if(o instanceof Integer) {
            double o1 = (double)((Integer) o);
            al.set(al.indexOf(o),o1);
        }
    }
    
     Collections.sort(al);
     System.out.println(al );
    
     Collections.sort(al,Collections.reverseOrder());
     System.out.println(al );
    

    Output:

     [-150, -210, -100, -112.5]
     [-210.0, -150.0, -112.5, -100.0]
     [-100.0, -112.5, -150.0, -210.0]
    

Hope it will help someone who is trying to sort integer and double values.

QualityMatters
  • 895
  • 11
  • 31