Проверка ответа массива JSON с несколькими записями в Java

#java #rest-assured

#java #будьте уверены

Вопрос:

У нас есть API, который выдает следующие ответы

 [
        {
            "subject": "English",            
            "Marks": "79"
        },
        {
           "subject": "Maths",            
            "Marks": "89"

        }
    ]
    
 

Нам нужно проверить это
Тема = английский и отметки = 79
Тема = Математика и оценки = 89

мы пытались, но безуспешно.

 JSONArray jsonarray = new JSONArray(strindentify);
            for (int i = 0; i < jsonarray.length(); i  ) {
                JSONObject jsonobject = jsonarray.getJSONObject(i);
                String type = jsonobject.getString("subject");
                Assert.assertEquals(type, "English");
                String value = jsonobject.getString("Marks");
                Assert.assertEquals(value, "79");
                System.out.println(" The Subject and Marks:-"  type  "and"  value );
            }
 

Необходимо утверждать, что Subject = Английский, затем Marks = 79 и т. Д

Комментарии:

1. Я полагаю, вы хотели сказать «Нужно утверждать, что если Subject=English, то Marks = 79″ . Это отсутствующее «if» является ключевым словом здесь, потому что для этого вам понадобится if оператор в вашем коде, а я не вижу ни одного из них. Попробуйте еще раз.

2. Можем ли мы получить представление о вашем импорте или происхождении hasItem(String) в этом тестовом примере?

Ответ №1:

В вашем утверждении есть проблема. Вы должны передать 2 строки в assertEquals:

 Assert.assertEquals(type, "English");
 

Комментарии:

1. Не зная источника hasItem() , вы не можете быть уверены, что строка не передается в качестве аргумента. Насколько вы видите hasItem() , может возвращать строковое значение. Хотя это кажется неэффективным, в лучшем случае это может быть допустимо.

2. Но тип — string var . и вам нужно просто проверить равенство 2 строк.

3. Да, я согласен с вами, но учтите следующее public String hasItem(String input) { return input; } . Вот почему я сказал, что это неэффективно. Этот пример будет работать в этом случае (несмотря на все, что с ним не так).

4. @Haris Мы изменили сценарий, пожалуйста, проверьте

Ответ №2:

Ваш цикл for проверяет оба объекта на каждой итерации. Вместо этого вы захотите получать отдельные значения ‘subject’ и ‘marks’ на каждой итерации и проверять свои условия на основе предмета.

Например:

 JSONArray jsonarray = new JSONArray(strindentify);

Assert.assertEquals(2, jsonarray.length, "Expected exactly 2 entries in array"); //optional

for (int i = 0; i < jsonarray.length(); i  ) {
    JSONObject jsonobject = jsonarray.getJSONObject(i);
    String type = jsonobject.getString("subject");
    String value = jsonobject.getString("Marks");
    System.out.println(" The Subject and Marks:-"  type  "and"  value );
    
    switch(type) {
         case "English": Assert.assertEquals(value, "79"); break;
         case "Maths": Assert.assertEquals(value, "89"); break;
         default: throw new RuntimeException("Unexpected subject"); //optional
    }
}
 

Обратите внимание на строки ‘// необязательно’, которые, соответственно, не пройдут тест, если в массиве больше или меньше 2 элементов, или если встречается какой-либо предмет, отличный от английского или математики.
Обратите внимание, что это не приводит к сбою в крайнем случае, когда массив содержит 2 записи, но обе являются английскими или обе являются математическими.

Я использовал a switch , который позволил бы вам легко добавлять другие комбинации предметов / меток. Конструкция if / else будет столь же допустимой. Просто не забудьте break , если вы используете switch !

Ответ №3:

 @Test
public void test_validJson() {
    String input = "Your_string_json_here";
    JSONArray jsonarray = new JSONArray(input);
    Assert.assertNotNull(jsonarray);
    for (int i = 0; i < jsonarray.length(); i  ) {
        JSONObject jsonobject = jsonarray.getJSONObject(i);
        Assert.assertNotNull(jsonobject);
        String subject = jsonobject.getString("subject");
        String value = jsonobject.getString("Marks");
        Assert.assertNotNull(subject);
        Assert.assertNotNull(value);
        switch(subject) {
            case "English" : 
                Assert.assertEquals(value, "79");
                break;
            case "Maths" :
                Assert.assertEquals(value, "89");
                break;
            default: 
            // Fail on unrecognized subject?
            throw new AssertionException();
        }
     }
}
 

Обратите внимание, что это приведет к сбою, если объект и / или значение отсутствуют, а также к сбою для неизвестных объектов. Это не дает никаких гарантий относительно длины массива или порядка элементов, например, английский ДОЛЖЕН быть первым элементом массива и т.д. Повторяющиеся объекты также не пройдут тест.Это просто подтверждает, что если в ответ включены заданные темы, то их соответствующие метки соответствуют указанным.

Измените это по своему вкусу.

РЕДАКТИРОВАТЬ: если вы хотите проверить, включены только выбранные темы:

 List<String> knownSubjects = Arrays.asList("History", "Maths", "English", "whatever");
Assert.assertTrue(knownSubjects.contains(subject));
 

Если вы хотите проверять только известные объекты с известными метками:

 Map<String, String> subjectMarks = new HashMap<>();
subjectMarks.put("English", "89");
subjectMarks.put("Maths", "79");
subjectMarks.put("Whatever", "10");

Assert.assertTrue(subjectMarks.keySet().contains(subject));
Assert.assertEquals(value, subjectMarks.get(subject));
 

Комментарии:

1. если subject не исправлен, оператор switch не будет работать, допустим, тема добавлена как история, наука, география и т. Д. Мы использовали операторы if и else, но нам нужна динамическая тема

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