@@ -28,33 +28,36 @@ include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/
2828[[scratch]]
2929== Starting with Spring Initializr
3030
31- You can use this https://start.spring.io/#!type=maven-project&language=java& packaging=jar&jvmVersion=11 &groupId=com.example&artifactId=testing-web&name=testing-web&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.testing-web &dependencies=web[pre-initialized project] and click Generate to download a ZIP file. This project is configured to fit the examples in this tutorial.
31+ You can use this https://start.spring.io/#!type=maven-project&packaging=jar&jvmVersion=17 &groupId=com.example&artifactId=testing-web&name=testing-web&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.testingweb &dependencies=web[pre-initialized project] and click Generate to download a ZIP file. This project is configured to fit the examples in this tutorial.
3232
3333To manually initialize the project:
3434
3535. Navigate to https://start.spring.io.
3636This service pulls in all the dependencies you need for an application and does most of the setup for you.
37- . Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java.
37+ . Choose either Gradle or Maven and the language you want to use: Kotlin or Java.
3838. Click *Dependencies* and select *Spring Web*.
3939. Click *Generate*.
4040. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.
4141
4242NOTE: If your IDE has the Spring Initializr integration, you can complete this process from your IDE.
4343
44- NOTE: You can also fork the project from Github and open it in your IDE or other editor.
44+ NOTE: You can also fork the project from GitHub and open it in your IDE or other editor.
4545
4646[[initial]]
4747== Create a Simple Application
4848
49- Create a new controller for your Spring application. The following listing (from
50- `src/main/java/com/example/testingweb/HomeController.java`) shows how to do so:
49+ Create a new controller for your Spring application. The following listing shows how to do so:
5150
52- ====
53- [source,java]
51+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
52+ .Java
5453----
5554include::complete/src/main/java/com/example/testingweb/HomeController.java[]
5655----
57- ====
56+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
57+ .Kotlin
58+ ----
59+ include::complete-kotlin/src/main/kotlin/com/example/testingweb/HomeController.kt[]
60+ ----
5861
5962NOTE: The preceding example does not specify `GET` versus `PUT`, `POST`, and so forth.
6063By default `@RequestMapping` maps all HTTP operations. You can use `@GetMapping` or
@@ -63,17 +66,20 @@ By default `@RequestMapping` maps all HTTP operations. You can use `@GetMapping`
6366
6467== Run the Application
6568
66- The Spring Initializr creates an application class (a class with a `main()` method) for
67- you. For this guide, you need not modify this class. The following listing (from
68- `src/main/java/com/example/testingweb/TestingWebApplication.java`) shows the application class that
69+ The Spring Initializr creates an application class (a class with a `main()` method) for you.
70+ For this guide, you need not modify this class. The following listing shows the application class that
6971the Spring Initializr created:
7072
71- ====
72- [source,java]
73+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
74+ .Java
7375----
7476include::complete/src/main/java/com/example/testingweb/TestingWebApplication.java[]
7577----
76- ====
78+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
79+ .Kotlin
80+ ----
81+ include::complete-kotlin/src/main/kotlin/com/example/testingweb/TestingWebApplication.kt[]
82+ ----
7783
7884`@SpringBootApplication` is a convenience annotation that adds all of the following:
7985
@@ -90,8 +96,8 @@ services in the package where your annotated `TestingWebApplication` class resid
9096
9197The `main()` method uses Spring Boot's `SpringApplication.run()` method to launch an
9298application. Did you notice that there is not a single line of XML? There is no `web.xml`
93- file, either. This web application is 100% pure Java and you did not have to deal with
94- configuring any plumbing or infrastructure. Spring Boot handles all of that for you.
99+ file, either. You do not have to deal with configuring any plumbing or infrastructure.
100+ Spring Boot handles all of that for you.
95101
96102Logging output is displayed. The service should be up and running within a few seconds.
97103
@@ -105,32 +111,38 @@ NOTE: Spring Boot assumes you plan to test your application, so it adds the nece
105111dependencies to your build file (`build.gradle` or `pom.xml`).
106112
107113The first thing you can do is write a simple sanity check test that will fail if the
108- application context cannot start. The following listing (from
109- `src/test/java/com/example/testingweb/TestingWebApplicationTest.java`) shows how to do so:
114+ application context cannot start. The following listing shows how to do so:
110115
111- ====
112- [source,java]
116+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
117+ .Java
113118----
114119include::initial/src/test/java/com/example/testingweb/TestingWebApplicationTests.java[]
115120----
116- ====
121+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
122+ .Kotlin
123+ ----
124+ include::initial-kotlin/src/test/kotlin/com/example/testingweb/TestingWebApplicationTests.kt[]
125+ ----
117126
118127The `@SpringBootTest` annotation tells Spring Boot to look for a main configuration class
119128(one with `@SpringBootApplication`, for instance) and use that to start a Spring
120129application context. You can run this test in your IDE or on the command line (by running
121130`./mvnw test` or `./gradlew test`), and it should pass. To convince yourself that the
122- context is creating your controller, you could add an assertion, as the following example
123- (from `src/test/java/com/example/testingweb/SmokeTest.java`) shows:
131+ context is creating your controller, you could add an assertion, as the following example shows:
124132
125- ====
126- [source,java]
133+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
134+ .Java
127135----
128136include::complete/src/test/java/com/example/testingweb/SmokeTest.java[]
129137----
130- ====
138+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
139+ .Kotlin
140+ ----
141+ include::complete-kotlin/src/test/kotlin/com/example/testingweb/SmokeTest.kt[]
142+ ----
131143
132144Spring interprets the `@Autowired` annotation, and the controller is injected before the
133- test methods are run. We use http://joel-costigliola .github.io/assertj /[AssertJ]
145+ test methods are run. We use a link: https://assertj .github.io/doc /[AssertJ]
134146(which provides `assertThat()` and other methods) to express the test assertions.
135147
136148NOTE: A nice feature of the Spring Test support is that the application context is cached
@@ -142,15 +154,18 @@ annotation.
142154It is nice to have a sanity check, but you should also write some tests that assert the
143155behavior of your application. To do that, you could start the application and listen for a
144156connection (as it would do in production) and then send an HTTP request and assert the
145- response. The following listing (from
146- `src/test/java/com/example/testingweb/HttpRequestTest.java`) shows how to do so:
157+ response. The following listing shows how to do so:
147158
148- ====
149- [source,java]
159+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
160+ .Java
150161----
151162include::complete/src/test/java/com/example/testingweb/HttpRequestTest.java[]
152163----
153- ====
164+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
165+ .Kotlin
166+ ----
167+ include::complete-kotlin/src/test/kotlin/com/example/testingweb/HttpRequestTest.kt[]
168+ ----
154169
155170Note the use of `webEnvironment=RANDOM_PORT` to start the server with a random port
156171(useful to avoid conflicts in test environments) and the injection of the port with
@@ -162,27 +177,33 @@ that, where Spring handles the incoming HTTP request and hands it off to your co
162177That way, almost all of the full stack is used, and your code will be called in exactly the
163178same way as if it were processing a real HTTP request but without the cost of starting the
164179server. To do that, use Spring's `MockMvc` and ask for that to be injected for you by
165- using the `@AutoConfigureMockMvc` annotation on the test case. The following listing (from
166- `src/test/java/com/example/testingweb/TestingWebApplicationTest.java`) shows how to do so:
180+ using the `@AutoConfigureMockMvc` annotation on the test case. The following listing shows how to do so:
167181
168- ====
169- [source,java]
182+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
183+ .Java
170184----
171185include::complete/src/test/java/com/example/testingweb/TestingWebApplicationTest.java[]
172186----
173- ====
187+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
188+ .Kotlin
189+ ----
190+ include::complete-kotlin/src/test/kotlin/com/example/testingweb/TestingWebApplicationTest.kt[]
191+ ----
174192
175193In this test, the full Spring application context is started but without the server. We
176194can narrow the tests to only the web layer by using `@WebMvcTest`, as the following
177- listing (from `src/test/java/com/example/testingweb/WebLayerTest.java`) shows:
195+ listing shows:
178196
179- ====
180- [source,java]
197+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
198+ .Java
199+ ----
200+ include::complete/src/test/java/com/example/testingweb/WebLayerTest.java[tags=test]
181201----
182- @WebMvcTest
183- include::complete/src/test/java/com/example/testingweb/WebLayerTest.java
202+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
203+ .Kotlin
204+ ----
205+ include::complete-kotlin/src/test/kotlin/com/example/testingweb/WebLayerTest.kt[tags=test]
184206----
185- ====
186207
187208The test assertion is the same as in the previous case. However, in this test, Spring Boot
188209instantiates only the web layer rather than the whole context. In an application with
@@ -191,37 +212,46 @@ example, `@WebMvcTest(HomeController.class)`.
191212
192213So far, our `HomeController` is simple and has no dependencies. We could make it more
193214realistic by introducing an extra component to store the greeting (perhaps in a new
194- controller). The following example (from
195- `src/main/java/com/example/testingweb/GreetingController.java`) shows how to do so:
215+ controller). The following example shows how to do so:
196216
197- ====
198- [source,java]
217+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
218+ .Java
199219----
200220include::complete/src/main/java/com/example/testingweb/GreetingController.java[]
201221----
202- ====
222+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
223+ .Kotlin
224+ ----
225+ include::complete-kotlin/src/main/kotlin/com/example/testingweb/GreetingController.kt[]
226+ ----
203227
204- Then create a greeting service, as the following listing (from
205- `src/main/java/com/example/testingweb/GreetingService.java`) shows:
228+ Then create a greeting service, as the following listing shows:
206229
207- ====
208- [source,java]
230+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
231+ .Java
209232----
210233include::complete/src/main/java/com/example/testingweb/GreetingService.java[]
211234----
212- ====
235+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
236+ .Kotlin
237+ ----
238+ include::complete-kotlin/src/main/kotlin/com/example/testingweb/GreetingService.kt[]
239+ ----
213240
214241Spring automatically injects the service dependency into the controller (because of the
215- constructor signature). The following listing (from
216- `src/test/java/com/example/testingweb/WebMockTest.java`) shows how to test this controller
242+ constructor signature). The following listing shows how to test this controller
217243with `@WebMvcTest`:
218244
219- ====
220- [source,java]
245+ [source,java,indent=0,subs="verbatim,quotes",role="primary"]
246+ .Java
221247----
222248include::complete/src/test/java/com/example/testingweb/WebMockTest.java[]
223249----
224- ====
250+ [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
251+ .Kotlin
252+ ----
253+ include::complete-kotlin/src/test/kotlin/com/example/testingweb/WebMockTest.kt[]
254+ ----
225255
226256We use `@MockBean` to create and inject a mock for the `GreetingService` (if you do not do
227257so, the application context cannot start), and we set its expectations using `Mockito`.
0 commit comments