【问题标题】:Karate array field become object空手道数组字段成为对象
【发布时间】:2018-05-29 09:05:58
【问题描述】:

我遇到了这个非常奇怪的问题。

我想将两个列表追加到一个列表中,但是空手道似乎不支持这个功能,所以我写了一个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)

不明白为什么有时候数组是数组,有时候变成对象?

【问题讨论】:

    标签: karate


    【解决方案1】:

    您可以尝试将 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)
    

    Result

    【讨论】:

      【解决方案2】:

      是的,默认情况下,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 甚至 mapfilter 操作,以使迭代更容易。也许我们需要karate.append()karate.merge()(用于合并 2 个 JSON 对象)。随时提出功能请求。

      【讨论】:

      • 感谢彼得的信息。但我对在同一个工具中使用 Java 和 JavaScript 感到困惑。你能解释一下我们什么时候应该使用 Java,什么时候应该使用 JavaScript?
      • 既然你接受了另一个答案,请问他:P
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      相关资源
      最近更新 更多