Поле массива каратэ становится объектом

У меня действительно странная проблема.

Я хочу добавить два списка в один список, но кажется, что каратэ не поддерживает эту функцию, поэтому я пишу функцию JS.

function(lists){
    var arr = []
    for each (var list in lists){
        for each (var item in list){
            arr.push(item);
        }
    }
    return arr;
}

И я пишу этот файл функций для тестирования:

Feature:
  Scenario:
    * def appendList = read('../utils/append-list.js')
    * def arr = [{a: 'a'}, {b: 'b'}, {c: 'c'}]
    * def arr1 = [{a: 'a'}, {b: 'b'}, {c: 'c'}]
    * def arr2 = appendList([arr, arr1])
    * print 'arr2', arr2
    * def xx = { aa: '#(arr2)' }
    * print 'xx', xx
    * copy yy = xx
    * print 'yy', yy
    * match xx == yy

Вот журнал:

16:00:28.424 [main] INFO  com.intuit.karate - [print] arr2 [
  {
    "a": "a"
  },
  {
    "b": "b"
  },
  {
    "c": "c"
  },
  {
    "a": "a"
  },
  {
    "b": "b"
  },
  {
    "c": "c"
  }
]

16:00:28.444 [main] INFO  com.intuit.karate - [print] xx {
  "aa": {
    "0": {
      "a": "a"
    },
    "1": {
      "b": "b"
    },
    "2": {
      "c": "c"
    },
    "3": {
      "a": "a"
    },
    "4": {
      "b": "b"
    },
    "5": {
      "c": "c"
    }
  }
}

16:00:28.466 [main] INFO  com.intuit.karate - [print] yy {
  "aa": [
    {
      "a": "a"
    },
    {
      "b": "b"
    },
    {
      "c": "c"
    },
    {
      "a": "a"
    },
    {
      "b": "b"
    },
    {
      "c": "c"
    }
  ]
}

16:00:28.469 [main] ERROR com.intuit.karate - assertion failed: path: $.aa, actual: [object Array], expected: [{"a":"a"},{"b":"b"},{"c":"c"},{"a":"a"},{"b":"b"},{"c":"c"}], reason: actual value is not list-like

com.intuit.karate.exception.KarateException: path: $.aa, actual: [object Array], expected: [{"a":"a"},{"b":"b"},{"c":"c"},{"a":"a"},{"b":"b"},{"c":"c"}], reason: actual value is not list-like

    at com.intuit.karate.StepDefs.matchNamed(StepDefs.java:540)
    at com.intuit.karate.StepDefs.matchEquals(StepDefs.java:526)
    at ✽.* match xx == yy(kromotus/test/test.feature:12)


com.intuit.karate.exception.KarateException: path: $.aa, actual: [object Array], expected: [{"a":"a"},{"b":"b"},{"c":"c"},{"a":"a"},{"b":"b"},{"c":"c"}], reason: actual value is not list-like

    at com.intuit.karate.StepDefs.matchNamed(StepDefs.java:540)
    at com.intuit.karate.StepDefs.matchEquals(StepDefs.java:526)
    at ✽.* match xx == yy(kromotus/test/test.feature:12)

Я не понимаю, почему иногда массив является массивом, иногда он становится объектом?

2 ответа

Решение

Вы можете попытаться преобразовать возвращаемые данные в функции JavaScript в JSON. Ниже объясняю, что происходит в каратэ, как я понимаю:

* def appendList = read('../utils/append-list.js')
* def arr = [{a: 'a'}, {b: 'b'}, {c: 'c'}]
* def arr1 = [{a: 'a'}, {b: 'b'}, {c: 'c'}]
* def arr2 = appendList([arr, arr1]) # return JS[] variable type instead of JSON object
* print 'arr2', arr2
* def xx = { aa: '#(arr2)' } 
* print 'xx', xx
* copy yy = xx
* print 'yy', yy
* match xx == yy

Ниже описано, как это исправить:

* def appendList = read('append-list.js')
* json arr = [{a: 'a'}, {b: 'b'}, {c: 'c'}]
* json arr1 = [{a: 'a'}, {b: 'b'}, {c: 'c'}]
* json arr2 = appendList([arr, arr1]) # convert to JSON
* print 'arr2', arr2
* json xx = { aa: '#(arr2)' }
* print 'xx', xx
* copy yy = xx
* print 'yy', yy
* match xx == yy

Информация журнала:

20:37:02.034 [main] WARN com.intuit.karate - skipping bootstrap configuration: could not find or read file: karate-config.js, prefix: CLASSPATH
20:37:02.139 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.142 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.149 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.149 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.168 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.169 [main] INFO com.intuit.karate - [print] arr2 [
  {
    "a": "a"
  },
  {
    "b": "b"
  },
  {
    "c": "c"
  },
  {
    "a": "a"
  },
  {
    "b": "b"
  },
  {
    "c": "c"
  }
]

20:37:02.173 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.177 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.178 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $['aa']
20:37:02.179 [main] DEBUG com.jayway.jsonpath.internal.JsonContext - Set path $['aa'] new value [{a=a}, {b=b}, {c=c}, {a=a}, {b=b}, {c=c}]
20:37:02.182 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.183 [main] INFO com.intuit.karate - [print] xx {
  "aa": [
    {
      "a": "a"
    },
    {
      "b": "b"
    },
    {
      "c": "c"
    },
    {
      "a": "a"
    },
    {
      "b": "b"
    },
    {
      "c": "c"
    }
  ]
}

20:37:02.188 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.188 [main] INFO com.intuit.karate - [print] yy {
  "aa": [
    {
      "a": "a"
    },
    {
      "b": "b"
    },
    {
      "c": "c"
    },
    {
      "a": "a"
    },
    {
      "b": "b"
    },
    {
      "c": "c"
    }
  ]
}

20:37:02.189 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
20:37:02.189 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $
1 Scenarios ([32m1 passed[0m)
10 Steps ([32m10 passed[0m)
0m0.680s
html report: (paste into browser to view)

Результат

Да, по умолчанию JSON внутренне преобразуется в списки Java, что может сбивать с толку. Лучше всего использовать "стиль Java" везде, где это возможно. При итерации используйте циклы for с индексами. Например, попробуйте это:

* def first = [{a: 1}, {b: 2}]
* def second = [{c: 3}, {d: 4}]
* eval first.addAll(second)
* print first

Это имеет тот же эффект, что и выше, но более запутанный:

* def append = function(f, s){ for (var i = 0; i < s.length; i++) { f.add(s[i]) }; return f }
* def first = [{a: 1}, {b: 2}]
* def second = [{c: 3}, {d: 4}]
* def result = append(first, second)
* print result

Обратите внимание, что мы используем Java List.add() а также List.addAll() методы, а не JS push, Конечно, вы можете написать свою собственную функцию, которая делает это за кулисами.

Кстати, следующая версия каратэ представит karate.forEach и даже map а также filter операции, чтобы сделать итерацию проще. Может нам нужен karate.append() а также karate.merge() (для объединения 2 объектов JSON). Не стесняйтесь поднять запрос функции.

Другие вопросы по тегам