2017-02-09 8 views
0

У меня ограниченный опыт работы с остальными. У нас есть несколько тестов, в которых я обычно могу найти примеры внутри или не удалять этот google, но я застреваю при попытке сопоставить вложенное свойство для элемента в анонимном массиве и проверить свойства вверх и вниз (кузены?) ,REST Assured: Как найти элемент с использованием вложенного свойства в JSON и проверить другие свойства

Пример JSON:

[ 
    { 
     "id":1, 
     "type":{ 
     "typeId":3, 
     "name":"LPM" 
     }, 
     "status":{ 
     "id":1, 
     "price":1.20, 
     "source":172, 
     "valid":0 
     } 
    }, 
    { 
     "id":2, 
     "type":{ 
     "typeId":2, 
     "name":"ST" 
     }, 
     "status":{ 
     "id":10, 
     "price":1.20, 
     "source":172, 
     "valid":0 
     } 
    } 
] 

Я использую будьте уверены, и я хочу, чтобы найти элемент в списке, который имеет type.name равным LPM, а затем проверить status.price, status.source и status.id из только что элемент.

Когда я сначала начал проверки ответов, это было возможно только за один пункт, чтобы быть в массиве, так что я использовал:

response.then() 
     .assertThat() 
     .body("size", greaterThan(0)) 
     .body("[0].type.name", equalToIgnoringCase("LPM")) 
     .body("[0].status.id", equalTo(statusId)) 
     .body("[0].status.source", equalTo(sourceId)) 
     .body("[0].status.price", equalTo(price)); 

Однако это уже не уверены на работу, так как может быть более одного элемента в массиве, и порядок не гарантируется.

Я изменил мои проверки тела, чтобы быть:

response.then() 
     .assertThat() 
     .body("size", greaterThan(0)) 
     .body("type.name", hasItem("LPM")) 
     .body("status.id", hasItem(statusId)) 
     .body("status.source", hasItem(sourceId)) 
     .body("status.price", hasItem(price)); 

Этого достаточно, чтобы получить тест пройти, но это вносит риск того, что status.id, status.source и status.price элемента с type.name LPM мог быть неправильным, но это не будет обнаружено, поскольку они будут сопоставлены с элементом с помощью type.name ST.

Так что я хочу, чтобы иметь возможность найти элемент, который имеет LPM, как это type.name, из которых я могу гарантировать там быть только один, а затем для status.id, status.source и status.price, проверить этот элемент только, т.е. НЕ элемент ST.

Я попытался изменить свой элемент управления телом, чтобы найти элементы с type.name, которые мне нужны, но я не могу заставить это работать, поскольку я не могу понять, как вернуться к дереву, , чтобы проверить другие атрибуты в одном элементе:

response.then() 
     .assertThat() 
     .body("size", greaterThan(0)) 
     .body("$.findAll (it.type.name = LPM}.status.id ", hasItem(statusId)) 
     .body("$.findAll (it.type.name = LPM}.status.source", hasItem(sourceId)) 
     .body("$.findAll (it.type.name = LPM}.status.price", hasItem(price)); 

Кроме того, даже если это работало, он будет искать дереву 3 раза, когда на самом деле когда-то сделал бы.

Мои средние матчи проходят этот тест, но я хочу, чтобы все было правильно. Я знаю, что я мог бы получить элементы в List и работать с ними, но для согласованности с остальными нашими примерами я бы предпочел, хотя в настоящее время я не вижу другого варианта.

Я попытался найти примеры того, что я пытаюсь сделать в документации, многоуровневых учебных пособий и примеров, но у меня их нет, поэтому всегда существует вероятность, что это на самом деле невозможно. Если нет, я с удовольствием воспитываю теорию, лежащую в ее основе.

Любая помощь приветствуется.

+0

Вы настаиваете на том, чтобы сделать это только witj REST? –

+0

@ GrzegorzGórkiewicz Да, я не хочу вводить другую структуру тестирования. Если я не смогу сделать это так, как хочу, тогда я десериализую json в List и перебираю его. – Clarkey

+0

Я не имел в виду еще один ** тест ** рамки. Я хотел использовать, например, GSON от Google, чтобы создать список JSONObjects, а затем утвердить с помощью Hamcrest, что этот список содержит элемент с требуемым свойством. –

ответ

4

Вот один из способов сделать это:

... 
then(). 
     root("find {it.type.name == '%s'}.status"). 
     body("id", withArgs("LPM"), is(1)). 
     body("price", withArgs("LPM"), is(1.20f)). 
     body("source", withArgs("LPM"), is(172)). 
     body("id", withArgs("ST"), is(10)); 

(вы можете явно извлечь withArgs переменной, а также во избежание повторения).

find Способ поиска Groovy первого элемента, соответствующего предикату ({it.type.name == '%s'}), findAll всегда будет возвращать список.

root инструктирует REST. Гарантируется использование «корневого пути», который используется в последующих ожиданиях (см. docs).

+0

Спасибо! Это сработало отлично. Это очень элегантное решение; гораздо более аккуратный, чем необходимость десериализации JSON и повторения. – Clarkey

+0

также мне явно нужно научиться отличным! – Clarkey

Смежные вопросы