Каратэ: Есть ли способ получить длину ключей объекта JSON из переменной Examples?

#karate

#karate

Вопрос:

У меня есть тест karate, который проходит:

   Scenario Outline: Find all the the prime factors in the range from <start> to <end> are <result>
    Given path '/primefactors'
    And param start = <start>
    And param end = <end>
    When method get
    Then status 200
    And match header content-type contains 'application/json'
    And match header content-type contains 'charset=utf-8'
    And match response == {numbers:<result>, start:<start>, end:<end>, count:<count>, type:PrimeFactors}
    Examples:
      | start | end | result                                       | count
      | 8     | 10  | {8: [2,2,2], 9:[3,3], 10:[2,5]}              | 3
      | 13    | 16  | {13: [13], 14:[2,7], 15:[3,5], 16:[2,2,2,2]} | 4
  

Однако то, что я хотел бы сделать, это не использовать переменную count из раздела Examples: и просто вывести count из длины количества ключей в переменной объекта result таким образом:

  Scenario Outline: Find all the the prime factors in the range from <start> to <end> are <result>
    Given path '/primefactors'
    And param start = <start>
    And param end = <end>
    When method get
    Then status 200
    And match header content-type contains 'application/json'
    And match header content-type contains 'charset=utf-8'
    And def result = <result>
    And match response == {numbers:<result>, start:<start>, end:<end>, count:'#(Object.keys(result).length)', type:PrimeFactors}
    Examples:
      | start | end | result                                        
      | 8     | 10  | {8: [2,2,2], 9:[3,3], 10:[2,5]}               
      | 13    | 16  | {13: [13], 14:[2,7], 15:[3,5], 16:[2,2,2,2]}  
  

Когда я пытаюсь это сделать, я получаю ошибку:

 primefactors.feature:33 - javascript evaluation failed: Object.keys(result).length, TypeError: {8=[2,2,2], 9=[3,3], 10=[2,5]} is not an Object in <eval> at line number 1

  

и тест завершается неудачей.

Учитывая, что Object.keys(result).length это допустимый JS (с использованием консоли разработчика Chrome):

 result = {8: [2,2,2], 9:[3,3], 10:[2,5]} 
{8: Array(3), 9: Array(2), 10: Array(2)}
Object.keys(result).length
3
  

Что я делаю не так? Каков правильный способ сделать это?

ОБНОВЛЕНИЕ (9 апреля 2019) Успешно работает следующее:

   Background:
    * url baseUrl
    * configure lowerCaseResponseHeaders = true
    * def keys = function(o){ return o.keySet() }
    * def values = function(o){ return o.values() }
    * def size = function(o){ return o.size() }

  Scenario Outline: Find all the the prime factors in the range from <start> to <end> are <result>
    Given path '/primefactors'
    And param start = <start>
    And param end = <end>
    When method get
    Then status 200
    And match header content-type contains 'application/json'
    And match header content-type contains 'charset=utf-8'
    And def result = <result>
    And match response == {numbers:<result>, start:<start>, end:<end>, count: '#(size(result))', type:PrimeFactors}
    Examples:
      | start | end | result
      | 8     | 10  | {8: [2,2,2], 9:[3,3], 10:[2,5]}
      | 13    | 16  | {13: [13], 14:[2,7], 15:[3,5], 16:[2,2,2,2]}
  

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

1. () => doWindmillKick();

Ответ №1:

Да, JS в Karate на самом деле не тот JS, который вы видите в дикой природе, и это может измениться, когда мы перейдем к Graal

Между тем, пожалуйста, используйте этот трюк, чтобы получить ключи, размер (и значения) из JSON:

 Scenario: json behaves like a java map within functions
  * def payload = { a: 1, b: 2 }
  * def keys = function(o){ return o.keySet() }
  * def values = function(o){ return o.values() }
  * def size = function(o){ return o.size() }
  * json result = keys(payload)
  * match result == ['a', 'b']
  * json result = values(payload)
  * match result == [1, 2]
  * def length = size(payload)
  * match length == 2
  

Вы должны иметь возможность использовать функцию во встроенных выражениях, например: '#(keys(foo))'

В будущем мы планируем добавить karate.keysOf() и karate.sizeOf() API, чтобы упростить это.

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

1. Используя ваше предложение, я могу получить ключи и значения, но, похоже, я не могу получить длину массива keys,

2. Да, это работает. Большое вам спасибо. Решение принято, и я обновил исходное сообщение обновленным тестом.