Как проверить, что элементы в json отсортированы по конкретному признаку?

java
groovy
soapui
Теги: #<Tag:0x00007fedc74749a8> #<Tag:0x00007fedc7474818> #<Tag:0x00007fedc74746d8>

(Tatyana Durova) #1

Как проверить, что элементы в json отсортированы по конкретному признаку, например по цвету:
Мне надо что-то типа
assert(isSort([{id:5, color:red}, {id:8, color:blue}{id:9, color:blue}{id:2, color:green}])) = false

assert(isSort([{id:9, color:blue}, {id:8, color:blue}{id:2, color:green}{id:5, color:red}])) = true

Нужно решение на groovy или java или намеки, как это сделать..


(Александр Таранков) #2

Для чего это нужно? Зачем проверять сортировку в JSON-объекте, который по сути не гарантирует порядок элементов


(rmerkushin) #3

Но если очень хочется, то наверное нужно юзать какой нибудь SortedMap ? (в джавах не очень разбираюсь smile ) Почитайте что то вроде этого.


(Tatyana Durova) #4

Хочется проверить что сортировка на сервере работает как надо, то етьс я делаю запрос, получаю json с элементами и проверяю что сортировка там действительно соблюдена. Я пишу тесты на АПИ где много сортировок на сервере. И как их проверять? Хочется иметь не только смоук тесты..


#5

Сортировка может быть сохранена в массиве, а не в объекте.

Для парсинга json есть разные библиотеки, можно выбирать "на вкус".
Не рекомендую Jackson, который любят разработчики, но под него надо создавать полноценные маппинги, что для теста, скорее всего, излишне.
Есть стандартная библиотека org.json (http://www.json.org/java/).
Есть com.google.gson (https://github.com/tflhyl/google-gson), довольно приятный в использвании.
В Groovy, возможно, есть что-то своё.

Сценарий обычно такой: создаем классы, на которые можно отобразить структуру JSON'а, парсим и далее проверяем готовые объекты в Java.


(Tatyana Durova) #6

То есть сначала все равно придется делать "образцовую структуру"? Если она у меня динамическая..я думала просто сравнивать два элемента по признаку и если один больше другого, то возвращать false, как то так..

Каким-нибудь легким изящным скриптиком =)


(Sergey Korol) #7

Не важно, динамическая она или нет. Полная структура объекта известна? Думаю да.
Когда будете читать из json в pojo, отсутствующие элементы просто будут null. Но ведь условие для сравнения вы задаете вручную, так? Т.е. если вы ассертите корректность сортировки по какому-то полю, вам однозначно известно, что оно != null, иначе весь смысл затеи теряется.

В похожей теме я привел пример, как распарсить json в POJO. Там же я намекнул, что стримы позволяют делать вам все что угодно с коллекциями, включая задания кастомных comparators. Для определения валидности порядка, вам нужно для начала привести коллекцию в отсортированный вид по цвету, аля expected result.

List<MyPojo> sortedPojo firstPojo.stream()
    .sorted((ob1, ob2) -> ob1.getColor().compareTo(ob2.getColor()))
    .collect(toList());

Затем, можно воспользоваться готовым методом isEqualList, входящим в состав апачевского ListUtils, для сравнения двух коллекций по цвету:

assertTrue(isEqualList(firstPojo.stream().map(MyPojo::getColor).collect(toList()), 
    sortedPojo.stream().map(MyPojo::getColor).collect(toList())));

(Tatyana Durova) #8

Таким образом я могу легко по любомум кастомному признаку делать сравнение, так ведь? Вроде бы звучит досточно хорошо...


#9

Можно и скриптиком, а при условии, что эта структура нигде больше не пригодится. Тогда есть резон не засорять тесты лишними классами. В общем, все в Ваших руках. Всегда можно распарсить динамически и поэлементно, если это выгодно. Я в Java в таких случаях использую JsonParser из Gson. А в другой ветке уже давали ссылку на JsonSlurper для Groovy.


(Sergey Korol) #10

Да, в выше приведенном примере достаточно передать любое из доступных свойств comparator'у.

List<MyPojo> sortedPojo firstPojo.stream()
     // getId(), getMagicWand(), etc.
    .sorted((ob1, ob2) -> ob1.getStatus().compareTo(ob2.getStatus()))
    .collect(toList());

Более того, вы можете вообще вынести comparator в качестве параметра метода сортировки:

public List<MyPojo> getSortedList(List<MyPojo> input, Comparator<MyPojo> comparator) {
    return input.stream().sorted(comparator).collect(toList());
}

// call
List<MyPojo> sortedByColors = getSortedList(firstPojo, 
        (ob1, ob2) -> ob1.getColor().compareTo(ob2.getColor()));

List<MyPojo> sortedByStatus = getSortedList(firstPojo, 
        (ob1, ob2) -> ob1.getStatus().compareTo(ob2.getStatus()));