瀏覽代碼

Fix tests up a bit and add documemtation

See gh-18
Dave Syer 9 年之前
父節點
當前提交
489d7ae669

+ 38
- 0
README.adoc 查看文件

@@ -136,6 +136,44 @@ $ curl localhost:8080
136 136
 Greetings from Spring Boot!
137 137
 ....
138 138
 
139
+== Add Unit Tests
140
+
141
+You will want to add a test for the endpoint you added, and Spring Test already provides some machinery for that, and it's easy to include in your project.
142
+
143
+Add this to your build file's list of dependencies:
144
+
145
+[source,groovy]
146
+----
147
+include::complete/build.gradle[tag=tests]
148
+----
149
+
150
+If you are using Maven, add this to your list of dependencies:
151
+
152
+[source,xml]
153
+----
154
+include::complete/pom.xml[tag=tests]
155
+----
156
+
157
+Now write a simple unit test that mocks the servlet request and response through your endpoint:
158
+
159
+`src/test/java/hello/HelloControllerTest.java`
160
+[source,java]
161
+----
162
+include::initial/src/test/java/hello/HelloControllerTest.java[]
163
+----
164
+
165
+Note the use of the `MockServletContext` to set up an empty `WebApplicationContext` so the `HelloController` can be created in the `@Before` and passed to `MockMvcBuilders.standaloneSetup()`. An alternative would be to create the full application context using the `Application` class and `@Autowired` the `HelloController` into the test. The `MockMvc` comes from Spring Test and allows you, via a set of convenient builder classes, to send HTTP requests into the `DispatcherServlet` and make assertions about the result.
166
+
167
+As well as mocking the HTTP request cycle we can also use Spring Boot to write a very simple full-stack integration test. For example, instead of (or as well as) the mock test above we could do this:
168
+
169
+`src/test/java/hello/HelloControllerTest.java`
170
+[source,java]
171
+----
172
+include::initial/src/test/java/hello/HelloControllerIT.java[]
173
+----
174
+
175
+The embedded server is started up on a random port by virtue of the `@IntegrationTest("${server.port=0}")` and the actual port is discovered at runtime with the `@Value("${local.server.port}")`.
176
+
139 177
 == Add production-grade services
140 178
 If you are building a web site for your business, you probably need to add some management services. Spring Boot provides several out of the box with its http://docs.spring.io/spring-boot/docs/{spring_boot_version}/reference/htmlsingle/#production-ready[actuator module], such as health, audits, beans, and more.
141 179
 

+ 2
- 0
complete/build.gradle 查看文件

@@ -26,7 +26,9 @@ dependencies {
26 26
     // tag::actuator[]
27 27
     compile("org.springframework.boot:spring-boot-starter-actuator")
28 28
     // end::actuator[]
29
+    // tag::tests[]
29 30
     testCompile("org.springframework.boot:spring-boot-starter-test")
31
+    // end::tests[]
30 32
 }
31 33
 
32 34
 task wrapper(type: Wrapper) {

+ 2
- 0
complete/pom.xml 查看文件

@@ -24,11 +24,13 @@
24 24
             <artifactId>spring-boot-starter-actuator</artifactId>
25 25
         </dependency>
26 26
         <!-- end::actuator[] -->
27
+        <!-- tag::tests[] -->
27 28
         <dependency>
28 29
             <groupId>org.springframework.boot</groupId>
29 30
             <artifactId>spring-boot-starter-test</artifactId>
30 31
             <scope>test</scope>
31 32
         </dependency>
33
+        <!-- end::tests[] -->
32 34
     </dependencies>
33 35
 
34 36
     <properties>

+ 1
- 1
complete/src/main/java/hello/HelloController.java 查看文件

@@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
6 6
 @RestController
7 7
 public class HelloController {
8 8
     
9
-    @RequestMapping("/hello")
9
+    @RequestMapping("/")
10 10
     public String index() {
11 11
         return "Greetings from Spring Boot!";
12 12
     }

+ 12
- 7
complete/src/test/java/hello/HelloControllerIT.java 查看文件

@@ -1,8 +1,14 @@
1 1
 package hello;
2 2
 
3
+import static org.hamcrest.Matchers.is;
4
+import static org.junit.Assert.assertThat;
5
+
6
+import java.net.URL;
7
+
3 8
 import org.junit.Before;
4 9
 import org.junit.Test;
5 10
 import org.junit.runner.RunWith;
11
+import org.springframework.beans.factory.annotation.Value;
6 12
 import org.springframework.boot.test.IntegrationTest;
7 13
 import org.springframework.boot.test.SpringApplicationConfiguration;
8 14
 import org.springframework.boot.test.TestRestTemplate;
@@ -11,22 +17,21 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 17
 import org.springframework.test.context.web.WebAppConfiguration;
12 18
 import org.springframework.web.client.RestTemplate;
13 19
 
14
-import java.net.URL;
15
-
16
-import static org.hamcrest.Matchers.is;
17
-import static org.junit.Assert.assertThat;
18
-
19 20
 @RunWith(SpringJUnit4ClassRunner.class)
20 21
 @SpringApplicationConfiguration(classes = Application.class)
21 22
 @WebAppConfiguration
22
-@IntegrationTest({"server.port=9090"})
23
+@IntegrationTest({"server.port=0"})
23 24
 public class HelloControllerIT {
25
+
26
+    @Value("${local.server.port}")
27
+    private int port;
28
+
24 29
 	private URL base;
25 30
 	private RestTemplate template;
26 31
 
27 32
 	@Before
28 33
 	public void setUp() throws Exception {
29
-		this.base = new URL("http://localhost:9090/hello");
34
+		this.base = new URL("http://localhost:" + port + "/");
30 35
 		template = new TestRestTemplate();
31 36
 	}
32 37
 

+ 7
- 8
complete/src/test/java/hello/HelloControllerTest.java 查看文件

@@ -1,27 +1,26 @@
1 1
 package hello;
2 2
 
3
+import static org.hamcrest.Matchers.is;
4
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
5
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
6
+
3 7
 import org.junit.Before;
4 8
 import org.junit.Test;
5 9
 import org.junit.runner.RunWith;
6 10
 import org.springframework.boot.test.SpringApplicationConfiguration;
7 11
 import org.springframework.http.MediaType;
8 12
 import org.springframework.mock.web.MockServletContext;
9
-import org.springframework.test.context.ContextConfiguration;
10 13
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 14
 import org.springframework.test.context.web.WebAppConfiguration;
12 15
 import org.springframework.test.web.servlet.MockMvc;
13 16
 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
14 17
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
15 18
 
16
-import static org.hamcrest.Matchers.is;
17
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
18
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
19
-
20 19
 @RunWith(SpringJUnit4ClassRunner.class)
21
-@SpringApplicationConfiguration(classes = Application.class)
22
-@ContextConfiguration(classes = MockServletContext.class)
20
+@SpringApplicationConfiguration(classes = MockServletContext.class)
23 21
 @WebAppConfiguration
24 22
 public class HelloControllerTest {
23
+
25 24
 	private MockMvc mvc;
26 25
 
27 26
 	@Before
@@ -31,7 +30,7 @@ public class HelloControllerTest {
31 30
 
32 31
 	@Test
33 32
 	public void getHello() throws Exception {
34
-		mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
33
+		mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
35 34
 				.andExpect(status().isOk())
36 35
 				.andExpect(content().string(is("Greetings from Spring Boot!")));
37 36
 	}

+ 0
- 18
initial/pom.xml 查看文件

@@ -14,28 +14,10 @@
14 14
     </parent>
15 15
 
16 16
     <dependencies>
17
-	    <!-- tag::jetty[] -->
18 17
         <dependency>
19 18
             <groupId>org.springframework.boot</groupId>
20 19
             <artifactId>spring-boot-starter-web</artifactId>
21
-            <exclusions>
22
-                <exclusion>
23
-                    <groupId>org.springframework.boot</groupId>
24
-                    <artifactId>spring-boot-starter-tomcat</artifactId>
25
-                </exclusion>
26
-	    </exclusions>
27 20
         </dependency>
28
-        <dependency>
29
-            <groupId>org.springframework.boot</groupId>
30
-            <artifactId>spring-boot-starter-jetty</artifactId>
31
-        </dependency>
32
-        <!-- end::jetty[] -->
33
-        <!-- tag::actuator[] -->
34
-        <dependency>
35
-            <groupId>org.springframework.boot</groupId>
36
-            <artifactId>spring-boot-starter-actuator</artifactId>
37
-        </dependency>
38
-        <!-- end::actuator[] -->
39 21
     </dependencies>
40 22
 
41 23
     <properties>