Я пытаюсь написать тестовые примеры Spock для своего приложения Spring Boot (версия: 2.7.5) и хочу создать документацию AsciiDoc с использованием Spring REST Docs. Может ли кто-нибудь предоставить пример фрагмента рабочего кода, демонстрирующего, как этого добиться?
Вот что я пробовал до сих пор:
build.gradle
plugins {
id 'org.springframework.boot' version '2.7.5'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'groovy'
id "org.asciidoctor.convert" version "1.5.8.1"
}
group = 'co.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
ext {
snippetsDir = file('build/generated-snippets')
}
dependencies {
...
implementation 'org.springframework.restdocs:spring-restdocs-restassured:2.0.5.RELEASE'
implementation 'org.springframework.restdocs:spring-restdocs-core:2.0.5.RELEASE'
implementation 'org.springframework.restdocs:spring-restdocs-asciidoctor:2.0.5.RELEASE'
testImplementation 'junit:junit:4.13.2'
...
}
test {
outputs.dir snippetsDir
}
asciidoctor {
inputs.dir snippetsDir
dependsOn test
}
Лидконтроллерспек
class LeadControllerSpec extends Specification {
@Rule
JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation() // TODO: need to give path
RequestSpecification documentationSpec
void setup() {
this.documentationSpec = new RequestSpecBuilder()
.addFilter(RestAssuredRestDocumentation.documentationConfiguration(restDocumentation)
.operationPreprocessors()
.withRequestDefaults(
Preprocessors.modifyUris().host('api.example.com')
.removePort())
.withResponseDefaults(Preprocessors.prettyPrint()))
.build()
}
void cleanup() {
}
def "test createLead endpoint"() {
when:
def response = RestAssured.given(this.documentationSpec)
.accept(MediaType.APPLICATION_JSON_VALUE)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body([
firstName: "John",
lastName: "Doe",
mobileNumber: "1234567890",
emailId: "[email protected]",
pincode: "12345",
cardScheme: "SchemeA"
])
.when()
.post("/api/v1/lead/create")
then:
response.statusCode == 200
}
}
Любая помощь будет оценена по достоинству. Заранее спасибо!
О, ок, я вижу. Тесты могут генерировать образцы выходных данных, которые затем можно включить в виде фрагментов примеров в asciidoc. Интересный. Как пользователь, не являющийся пользователем Spring, я понятия не имел, что делает Spring REST Docs.
Ваш код с @Rule
выглядит как JUnit 4, но Spock 2.x основан на JUnit 5, т. е. этот подход, вероятно, не работает, если только вы не работаете со Spock 1.x.
Мне было любопытно, и я попытался создать проект Maven с нуля — извините, пожалуйста, преобразуйте его в Gradle самостоятельно:
https://github.com/kriegaex/SO_Spock_SpringRESTDocs_78424426
Образец заявления выглядит следующим образом:
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplication(Application.class).run(args);
}
@RestController
private static class SampleController {
@RequestMapping("/")
public String index() {
return "Hello, World";
}
}
}
Соответствующая спецификация Спока выглядит так:
package org.example
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.restdocs.ManualRestDocumentation
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.web.context.WebApplicationContext
import spock.lang.Specification
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
@SpringBootTest(classes = [Application])
class MyControllerSpec extends Specification {
def restDocumentation = new ManualRestDocumentation()
@Autowired
WebApplicationContext context
MockMvc mockMvc
def setup() {
mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(documentationConfiguration(restDocumentation))
.build()
restDocumentation.beforeTest(getClass(), specificationContext.currentFeature.displayName)
}
def cleanup() {
restDocumentation.afterTest()
}
def "should document the GET /hello endpoint"() {
expect:
mockMvc
.perform(get("/"))
.andExpect(status().isOk())
.andDo(document("sample"))
}
}
По сути, я скорректировал ручную настройку, описанную в руководстве для настроек, отличных от JUnit , для Спока. Из предоставленного примера проекта я скопировал код для TestNG.
Было немного сложно согласовать различные версии продукта для Spring и Spring REST Docs, а также хорошо работать со Споком, но в моем примере проекта теперь все работает нормально. Сгенерированная HTML-страница из asciidoc с включенными фрагментами выглядит следующим образом:
Отказ от ответственности: есть вероятность, что моя конфигурация несовершенна и ее можно улучшить. Но я никогда раньше не использовал Spring REST Docs и даже не знаю Spring.
Спасибо, Кригаекс. Ваше предложение отлично работает. Я заметил две проблемы в своем коде: одна связана с использованием зависимости RestAssured, которая выдает ошибку «отказано в соединении», если серверное приложение не запускается явно, а вторая — несовместимая версия JUnit.
Добро пожаловать в СО. Тот факт, что на ваш вопрос не последовало никакой реакции, естественно, объясняется его трудностью для понимания. Не могли бы вы подробнее объяснить, как связаны тестирование REST API и создание документации для него? Я не вижу никакой связи вообще, но, возможно, я просто недостаточно знаю о вашем варианте использования.