Dopasowywanie częściowych obiektów do danych tabeli [duplikat]

Nov 20 2020

Obecnie oceniam karate jako zamiennik dla naszych własnych testów API. Mam usługę zwracającą takie dane:

{
  "items": [
    {
      "id": "1",
      "enabled": true,
      "foo": 1,
    },
    ...
  ],
  ...
}

Właściwości w każdym elemencie mają różne cechy i chciałbym przetestować je oddzielnie.

Na przykład, aby przetestować aktywację pozycji, chciałbym sprawdzić, czy enabledwłaściwość ma poprawną wartość dla podanej id.

Próbowałem to ustawić w ten sposób;

Feature: Partial object matching
  Background:
    Given table items
    |id  |enabled|
    | '1'|true   |
    | '2'|true   |
    | '3'|false  |

  Scenario: match with all properties specified -- this passes
    * def response = { items: [ { id: '3', enabled: false }, { id: '1', enabled: true }, { id: '2', enabled: true } ] }
    * match $response.items contains only items Scenario: match with partial properties -- how can I make this pass (while also testing for something sensible)? * def response = { items: [ { id: '3', enabled: false, foo: 1 }, { id: '1', enabled: true, foo: 1 }, { id: '2', enabled: true, foo: 1 } ] } * match $response.items contains only items

Rzeczywiste itemobiekty są dość masywne, zawierają znacznie więcej właściwości i obiektów zagnieżdżonych, dlatego wolałbym nie określać pełnej oczekiwanej struktury, ponieważ odnoszą się one do wielu różnych cech, a niektóre właściwości mają charakter dynamiczny.

Czy istnieje elegancki sposób, matchaby to zrobić, czy muszę uciekać się do skryptów?

Odpowiedzi

2 HenrikGustafsson Nov 20 2020 at 16:12

Wydaje się, że jest to właściwe rozwiązanie;

Feature: Partial object matching
  Background:
    Given def filterTableKeys = read('filterTableKeys.js')
    Given table items
    |id  |enabled|
    | '1'|true   |
    | '2'|true   |
    | '3'|false  |

  Scenario: match with all attributes
    * def response = { items: [ { id: '3', enabled: false }, { id: '1', enabled: true }, { id: '2', enabled: true } ] }
    * match $response.items contains only items Scenario: match with partial attributes * def response = { items: [ { id: '3', enabled: false, foo: 1 }, { id: '1', enabled: true, foo: 1 }, { id: '2', enabled: true, foo: 1 } ] } * def responseItems = $response.items
    * def responseItems2 = filterTableKeys(responseItems, items)
    * match responseItems2 contains only items

gdzie filterTableKeys.jsjest zdefiniowany jako

function fn(items, table) {
    var mapper = function(v) { return karate.filterKeys(v, table[0]) }
    return karate.map(items, mapper)
}

Nie wydaje się to jednak zbyt eleganckie, więc wszelkie wskazówki, jak można to zrobić, byłyby bardziej deklaratywne / mniej imperatywne / „skryptowe”.


Edytować

Jak zauważył Babu Sekaran poniżej, wydaje się to dobrze działać

  Scenario: match with partial attributes
    * def response = { items: [ { id: '3', enabled: false, foo: 1 }, { id: '1', enabled: true, foo: 1 }, { id: '2', enabled: true, foo: 1 } ] }
    * match $response.items contains deep items