Может ли Spring Cloud Contracts обрабатывать повторяющиеся запросы с разными кодами возврата HTTP? - PullRequest
0 голосов
/ 28 февраля 2020

Я работаю над небольшой службой REST, которая обрабатывает некоторые данные и сохраняет их (в настоящее время Oracle, работает над добавлением кэширования).

Мы начинаем работать с потребительскими контрактами, используя Spring Cloud Contract. фреймворк. У нас возникают проблемы при определении одного контракта о том, как мы намереваемся реализовать сервис.

У нас есть конечная точка PUT, которая принимает поле ввода в теле, которое является первичным ключом в нашей персистентности. В нашем сервисе мы ищем это поле в БД, и, если оно есть, мы хотим вернуть существующие данные из БД с кодом состояния 200, означающим, что новая запись не была добавлена. Если это значение еще не в БД, у нас есть лог c, чтобы сгенерировать для него данные и вставить данные в БД. Затем мы хотим вернуть 201, чтобы показать, что данные были созданы.

У нас есть рабочий контракт для случая 201, потому что когда запускаются сгенерированные JUnits, данных не существует, и он возвращает 201. Но наш потребитель также хочет получить контракт для сценария 200.

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

Наш контракт выглядит следующим образом (сокращен, но по существу то же самое):

Contract.make {
    name("givenValidInputs_returnDataAndCreatedStatus")
    request {
        method 'PUT'
        url "/path/to/resource"
        headers {
            contentType("application/json")
        }
        body(
                "primaryKey": $(p('1234567890123456'), c(regex('^[0-9]+$')))
        )
    }
    response {
        status 201
        body(
                "generatedValue": $(p(regex('^[0-9a-zA-Z]+$')), c('abc123'))   
        )
    }
}

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

Контрактные тесты предназначены для проверки технического рукопожатия конечной точки. Он не должен использоваться для проверки поведения (с сохранением состояния). Разницу в http-кодах между 200 и 201 можно считать крайним случаем, но, по моему мнению, это semanti c one.

Поэтому я согласен с Marcin Grzejszczak в том, что вам следует издеваться над сервисом. С этим поддельным сервисом вы можете смоделировать поведение, если действительно настаиваете на определении контракта для указанного c http кода.

За исключением сценария ios, вы можете указать конкретный c первичный ключ, который будет представлять ситуацию, которая уже существует. Единственная проблема заключается в том, что когда потребитель вызывает «99999999», когда он вызывает заглушку, он будет соответствовать обоим контрактам (поскольку это значение также соответствует предоставленному регулярному выражению в контракте 201).

Если вы просто добавите «приоритет: 1» к контракту, контракт 200 будет иметь приоритет над контрактом 201, если задано свойство c.

Contract.make {
    name("when put existing, expect 200")
    request {
        method 'PUT'
        url "/path/to/resource"
        headers {
            contentType("application/json")
        }
        body(
                "primaryKey": "99999999"
        )
    }
    response {
        status 200
        body(
                "generatedValue": $(p(regex('^[0-9a-zA-Z]+$')), c('abc123'))   
        )
    }
    priority 1
}

Вкл. со стороны производителя, вам нужно будет посмеяться над вашим сервисом, чтобы он правильно ответил, когда указано значение «99999999».

Я не думаю, что лично включил бы этот http-код в контрактные тесты, так как он представляет поведение с состоянием и, таким образом, является semanti c, а не техническим требованием подключения, по моему мнению. С обеих сторон я бы протестировал поведение данной ситуации в неинтеграционном модульном тесте. Хотя иногда бывает трудно отделить синтати c от семанти c в подобных ситуациях.

0 голосов
/ 02 марта 2020

Здесь нужно обсудить две вещи. Давайте начнем с первого, более важного. При выполнении контрактных тестов вы не должны обращаться к базе данных. Если вы делаете это, вы тестируете не только взаимодействие с контроллером, но и все другие уровни. Смоделируйте службу в вашем контроллере и только затем запустите контрактные тесты.

Что касается второго - изменившего ответ на тот же запрос, вы можете использовать для этого сценарии ios aka заглушки с отслеживанием состояния. Пожалуйста, проверьте документы здесь https://cloud.spring.io/spring-cloud-static/spring-cloud-contract/2.2.1.RELEASE/reference/html/project-features.html#contract -состояния-контракты

...