Используя тест Спока, как проверять пары ключ-значение атрибутов json, мы получаем динамически - PullRequest
0 голосов
/ 28 мая 2018

Как правильно написать тест, чтобы проверить приведенные ниже данные CSV, хранящиеся в таблице базы данных.Во входных данных, кроме элемента, все может быть необязательным.В этом элементе является ключ, остальное все идет как часть формата json, как обычно это выглядит в базе данных {"brand": "Brand6", "category": "Category6", "subcategory": "Sub-Category6"}

Ввод:

item,category,subcategory,brand,type,feature
TEST-ITEM6,Category6,Sub-Category6,Brand6
TEST-ITEM7,Category7,Sub-Category7,Brand7,TYPE7,FEATURE7
TEST-ITEM8,Category8,Sub-Category8,Brand8,TYPE8,FEATURE8

Испытание выполнено:

def "Case 3a. Verify New 2 records with two more additional fields along with earlier fields to the same tenant"() {
        expect:
            sql().eachRow("SELECT * FROM item WHERE item IN ('"+item+"')") { row ->

            def dbItem = row[0]
            def dbAttributes = getJsonToObject(row[1])

            def dbCategory = dbAttributes.getAt("category").toString()
            def dbSubCategory = dbAttributes.getAt("subcategory").toString()
            def dbBrand = dbAttributes.getAt("brand").toString()
            def dbType = dbAttributes.getAt("type").toString()
            def dbFeature = dbAttributes.getAt("feature").toString()

            assert dbItem == item
            assert category == dbCategory
            assert subcategory == dbSubCategory
            assert brand == dbBrand
            assert type == dbType
            assert feature == dbFeature
        }

        where:
        item << ['TEST-ITEM6', 'TEST-ITEM7', 'TEST-ITEM8']
        category << ['Category6','Category7', 'Category8']
        subcategory << ['Sub-Category6','Sub-Category7', 'Sub-Category8']
        brand << ['Brand6','Brand7', 'Brand8']
        type <<  ['TYPE7', 'TYPE8']
        feature << ['FEATURE7', 'FEATURE8']
    }

Ошибка:

Condition not satisfied:

type == dbType
|    |  |
TYPE8|  TYPE7
     false
     1 difference (80% similarity)
     TYPE(8)
     TYPE(7)

Expected :TYPE7

Actual   :TYPE8

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Для необязательных полей вы можете использовать оператор Элвиса ?: следующим образом (извините, длинный код, я смоделировал вашу базу данных и два новых тестовых примера, один со многими дополнительными полями и один неудачный тест):

package de.scrum_master.stackoverflow

import spock.lang.Specification
import spock.lang.Unroll

class DataTableWithOptionalItemsTest extends Specification {
  @Unroll
  def "Case 3a. Verify record '#item' with possibly optional fields"() {
    expect:
    testData[item].each { row ->
      def dbItem = row["item"]
      def dbCategory = row["category"]
      def dbSubCategory = row["subcategory"]
      def dbBrand = row["brand"]
      def dbType = row["type"]
      def dbFeature = row["feature"]

      assert dbItem == item
      assert (category ?: dbCategory) == dbCategory
      assert (subcategory ?: dbSubCategory) == dbSubCategory
      assert (brand ?: dbBrand) == dbBrand
      assert (type ?: dbType) == dbType
      assert (feature ?: dbFeature) == dbFeature
    }

    where:
    item         | category    | subcategory     | brand    | type    | feature
    'TEST-ITEM6' | 'Category6' | 'Sub-Category6' | 'Brand6' | null    | null
    'TEST-ITEM7' | 'Category7' | 'Sub-Category7' | 'Brand7' | 'TYPE7' | 'FEATURE7'
    'TEST-ITEM8' | 'Category8' | 'Sub-Category8' | 'Brand8' | 'TYPE8' | 'FEATURE8'
    'TEST-ITEM9' | null        | null            | null     | null    | null
    'TEST-FAIL'  | 'CategoryX' | 'Sub-CategoryX' | 'BrandX' | 'TYPEX' | 'FEATUREX'
  }

  static final testData = [
    'TEST-ITEM6': [
      [
        item       : 'TEST-ITEM6',
        category   : 'Category6',
        subcategory: 'Sub-Category6',
        brand      : 'Brand6',
        type       : 'dummy',
        feature    : null
      ],
      [
        item       : 'TEST-ITEM6',
        category   : 'Category6',
        subcategory: 'Sub-Category6',
        brand      : 'Brand6',
        type       : null,
        feature    : "foo"
      ]
    ],
    'TEST-ITEM7': [
      [
        item       : 'TEST-ITEM7',
        category   : 'Category7',
        subcategory: 'Sub-Category7',
        brand      : 'Brand7',
        type       : 'TYPE7',
        feature    : 'FEATURE7'
      ],
      [
        item       : 'TEST-ITEM7',
        category   : 'Category7',
        subcategory: 'Sub-Category7',
        brand      : 'Brand7',
        type       : 'TYPE7',
        feature    : 'FEATURE7'
      ]
    ],
    'TEST-ITEM8': [
      [
        item       : 'TEST-ITEM8',
        category   : 'Category8',
        subcategory: 'Sub-Category8',
        brand      : 'Brand8',
        type       : 'TYPE8',
        feature    : 'FEATURE8'
      ],
      [
        item       : 'TEST-ITEM8',
        category   : 'Category8',
        subcategory: 'Sub-Category8',
        brand      : 'Brand8',
        type       : 'TYPE8',
        feature    : 'FEATURE8'
      ]
    ],
    'TEST-ITEM9': [
      [
        item       : 'TEST-ITEM9',
        category   : 'Category1',
        subcategory: 'Sub-Category1',
        brand      : 'Brand1',
        type       : 'TYPE1',
        feature    : 'FEATURE1'
      ],
      [
        item       : 'TEST-ITEM9',
        category   : null,
        subcategory: null,
        brand      : null,
        type       : null,
        feature    : null
      ]
    ],
    'TEST-FAIL' : [
      [
        item       : 'TEST-FAIL',
        category   : 'CategoryX',
        subcategory: 'Sub-CategoryX',
        brand      : 'BrandY',
        type       : 'TYPEX',
        feature    : 'FEATUREX'
      ]
    ]
  ]
}
0 голосов
/ 29 мая 2018

В этом случае я бы порекомендовал использовать Таблицы данных , так как он становится более читабельным и более близко напоминает ваш ввод.

И хотя тип и функция являются необязательными, вам необходимо предоставить некоторыезначение для этого.Это может быть null или пустой List или Map (если элемент может иметь более одного типа / функции)

Таким образом, ваш where блок может выглядеть следующим образом:

item | category | subcategory | brand | typeFeatureMap
'TEST-ITEM6' | 'Category6' | 'Sub-Category6' | 'Brand6' | [:] // empty
'TEST-ITEM7' | 'Category7' | 'Sub-Category7' | 'Brand7' | ['TYPE7':'FEATURE7']
'TEST-ITEM8' | 'Category8' | 'Sub-Category8' | 'Brand8' | ['TYPE8':'FEATURE8']

Я бы также порекомендовал собрать данные и затем сравнить их, чтобы вы могли обойти проблемы с заказом.

Итак, пока ваш eachRow сделает что-то вроде

def itemFeatures = [:]

В вашем eachRow сделайте что-то вроде

itemFeatures.put(dbAttributes.getAt("type").toString(), dbAttributes.getAt("feature").toString())

И после этого

itemFeatures == typeFeatureMap

Не отвечая на ваш вопрос, я бы порекомендовал подумать об отделении тестов от вашей базы данных, если это возможно,Если вы создадите отдельные тесты для уровня абстракции базы данных и вашей бизнес-логики, вы будете более счастливы в долгосрочной перспективе;)

...