Skip to content

Commit

Permalink
Fix tests up a bit and add documemtation
Browse files Browse the repository at this point in the history
See gh-18
  • Loading branch information
dsyer committed Jan 5, 2015
1 parent 6d98b87 commit 489d7ae
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 34 deletions.
38 changes: 38 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,44 @@ $ curl localhost:8080
Greetings from Spring Boot!
....

== Add Unit Tests

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.

Add this to your build file's list of dependencies:

[source,groovy]
----
include::complete/build.gradle[tag=tests]
----

If you are using Maven, add this to your list of dependencies:

[source,xml]
----
include::complete/pom.xml[tag=tests]
----

Now write a simple unit test that mocks the servlet request and response through your endpoint:

`src/test/java/hello/HelloControllerTest.java`
[source,java]
----
include::initial/src/test/java/hello/HelloControllerTest.java[]
----

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.

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:

`src/test/java/hello/HelloControllerTest.java`
[source,java]
----
include::initial/src/test/java/hello/HelloControllerIT.java[]
----

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}")`.

== Add production-grade services
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.

Expand Down
2 changes: 2 additions & 0 deletions complete/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ dependencies {
// tag::actuator[]
compile("org.springframework.boot:spring-boot-starter-actuator")
// end::actuator[]
// tag::tests[]
testCompile("org.springframework.boot:spring-boot-starter-test")
// end::tests[]
}

task wrapper(type: Wrapper) {
Expand Down
2 changes: 2 additions & 0 deletions complete/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- end::actuator[] -->
<!-- tag::tests[] -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- end::tests[] -->
</dependencies>

<properties>
Expand Down
2 changes: 1 addition & 1 deletion complete/src/main/java/hello/HelloController.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
@RestController
public class HelloController {

@RequestMapping("/hello")
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
Expand Down
19 changes: 12 additions & 7 deletions complete/src/test/java/hello/HelloControllerIT.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package hello;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

import java.net.URL;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
Expand All @@ -11,22 +17,21 @@
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.client.RestTemplate;

import java.net.URL;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest({"server.port=9090"})
@IntegrationTest({"server.port=0"})
public class HelloControllerIT {

@Value("${local.server.port}")
private int port;

private URL base;
private RestTemplate template;

@Before
public void setUp() throws Exception {
this.base = new URL("http://localhost:9090/hello");
this.base = new URL("http://localhost:" + port + "/");
template = new TestRestTemplate();
}

Expand Down
15 changes: 7 additions & 8 deletions complete/src/test/java/hello/HelloControllerTest.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
package hello;

import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@ContextConfiguration(classes = MockServletContext.class)
@SpringApplicationConfiguration(classes = MockServletContext.class)
@WebAppConfiguration
public class HelloControllerTest {

private MockMvc mvc;

@Before
Expand All @@ -31,7 +30,7 @@ public void setUp() throws Exception {

@Test
public void getHello() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(is("Greetings from Spring Boot!")));
}
Expand Down
18 changes: 0 additions & 18 deletions initial/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,10 @@
</parent>

<dependencies>
<!-- tag::jetty[] -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!-- end::jetty[] -->
<!-- tag::actuator[] -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- end::actuator[] -->
</dependencies>

<properties>
Expand Down

1 comment on commit 489d7ae

@igilham
Copy link

@igilham igilham commented on 489d7ae Jan 5, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me; tidies up my mess in any case.

Please sign in to comment.