The document discusses testing approaches for microservices, including unit tests, integration tests, and end-to-end tests. It advocates for an outside-in development approach using behavior-driven development (BDD) with automated tests written at multiple levels to ensure software delivers expected functionality. BDD involves collaboratively defining requirements as structured scenarios to guide development and act as executable tests.
55. To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
56. To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
57. To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
58. To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
59. To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
60. To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
61. “We test our micro-services so we can deploy new
features quickly and with confidence”
69. To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
70. To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
71. To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
72. To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
73. To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
74. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
75. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
76. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
77. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
78. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
79. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
80. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
81. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
82. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
83. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
84. The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
85. How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
86. How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
87. How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
88. How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
89. How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
90. How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
96. A different testing pyramid
Slow-running executable
technical specifications
Executable Business
Specifications
97. A different testing pyramid
Fast-running executable technical
specifications
Slow-running executable
technical specifications
Executable Business
Specifications
98. Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Executable
Business specs
99. Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Executable
Business specs
Scenario: Search movies by director
Given the catalog has the following movies:
| title | director | actors |
| Gladiator | Ridley Scott | Russel Crowe, Joaquin Phoenix |
| Letters from Iwo Jima | Clint Eastwood | Ken Watanabe |
| Gran Torino | Clint Eastwood | Clint Eastwood, Bee Vang |
When I search for movies directed by Clint Eastwood
Then I should be presented with the following movies:
| title | director | actors |
| Letters from Iwo Jima | Clint Eastwood | Ken Watanabe |
| Gran Torino | Clint Eastwood | Clint Eastwood, Bee Vang |
100. Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Slow-running
technical
specs
101. Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Slow-running
technical
specs
@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class)
@WebAppConfiguration
@IntegrationTest("server.port:0")
class WhenFindingMoviesViaTheRestAPI extends Specification {
@Autowired
MovieRepository movieRepository;
@Value('${local.server.port}')
int port;
def "should list movies by director"() {
given:
movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])
when:
List<Movie> movies = when().get("/movies/findByDirector/Clint Eastwood").as(List)
then:
movies.collect {movie -> movie.title} == ["Letters from Iwo Jima", "Gran Torino"]
}
102. Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Fast-
running
technical
specs
103. Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Fast-
running
technical
specs
def setup() {
repository = Mock(MovieRepository)
artistService = new ArtistService(movieRepository: repository)
}
def "should build actor details from films the artist has acted in and has directed"() {
given: "Clint Eastwood has directed some films"
repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
and: "Clint Eastwood has starred in some films"
repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
when:
def artistDetails = artistService.findArtistByName("Clint Eastwood")
then:
artistDetails.isPresent()
and:
artistDetails.get().name == "Clint Eastwood" &&
artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
}
Spock
104. Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Fast-
running
technical
specs
105. Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Fast-
running
technical
specs
class MovieControllerSpecs extends Specification {
MovieRepository movieRepository = Mock()
def "should find by director regardless of case (#director -> #filteredDirector)"() {
given:
def controller = new MovieController(repository: movieRepository)
when:
controller.findByDirector(director)
then:
1*movieRepository.findByDirector(filteredDirector)
where:
director | filteredDirector
"Clint Eastwood" | "Clint Eastwood"
"Clint eastwood" | "Clint Eastwood"
Spock
107. Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping Cart
Service
Delivery Service
REST/HTTP
108. Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Delivery
Service
109. Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Consumer
Delivery
Service
110. Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Consumer
Producer
Delivery
Service
111. Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Consumer
Producer
Contract
Delivery
Service
112. Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Contract
Delivery
Service
113. Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
Delivery
Service
REST/HTTP
Contract
Mock
Shopping
Cart
Service
136. Pact and Pacto
Consumer Driven Contract Testing
42
Consumer Movie Catalog
Service
Mock
Service
Pact help us create and
configure a mock service
137. Pact and Pacto
Consumer Driven Contract Testing
43
Consumer Movie Catalog
Service
Mock
Service
138. Pact and Pacto
Consumer Driven Contract Testing
43
Consumer Movie Catalog
Service
Mock
Service
We write specifications to
describe the expected
behaviour of the service
139. Pact and Pacto
Consumer Driven Contract Testing
44
Consumer Movie Catalog
Service
Mock
Service
140. Pact and Pacto
Consumer Driven Contract Testing
44
Consumer Movie Catalog
Service
Mock
Service
When we run these
specifications, the expected
behaviour is recorded in a
‘pact’ file
asdasdasda
asdasdasdas
asdasdasd
asdasdasda
asdasdasdasd
asdasdasdasd
asdasdasdas
141. Pact and Pacto
Consumer Driven Contract Testing
45
Consumer Movie Catalog
Service
Mock
Service
asdasdasda
asdasdasdas
asdasdasd
asdasdasda
asdasdasdasd
asdasdasdasd
asdasdasdas
142. Pact and Pacto
Consumer Driven Contract Testing
45
Consumer Movie Catalog
Service
Mock
Service
We can now use this ‘pact’ to
test(drive) the service
implementation
asdasdasda
asdasdasdas
asdasdasd
asdasdasda
asdasdasdasd
asdasdasdasd
asdasdasdas
148. Feature: Adding new movies
In order to sell more movies
As an online movie seller
I want to be able to add movies to the catalog
Scenario: Adding movies
Given the following movie has just come out
| title | director | actors |
| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
When I add this movie to the catalog
Then I should be able to find it in the catalog
149. Feature: Adding new movies
In order to sell more movies
As an online movie seller
I want to be able to add movies to the catalog
Scenario: Adding movies
Given the following movie has just come out
| title | director | actors |
| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
When I add this movie to the catalog
Then I should be able to find it in the catalog
150. Feature: Adding new movies
In order to sell more movies
As an online movie seller
I want to be able to add movies to the catalog
Scenario: Adding movies
Given the following movie has just come out
| title | director | actors |
| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
When I add this movie to the catalog
Then I should be able to find it in the catalog
@When("I add this movie to the catalog")
public void addMovieToCatalog() {
movieId = rest().given().contentType("application/json")
.content(newMovie)
.post("/movies")
.then().statusCode(200)
.and().extract().jsonPath().getString("id");
}
151. Feature: Adding new movies
In order to sell more movies
As an online movie seller
I want to be able to add movies to the catalog
Scenario: Adding movies
Given the following movie has just come out
| title | director | actors |
| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
When I add this movie to the catalog
Then I should be able to find it in the catalog
152. Feature: Adding new movies
In order to sell more movies
As an online movie seller
I want to be able to add movies to the catalog
Scenario: Adding movies
Given the following movie has just come out
| title | director | actors |
| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
When I add this movie to the catalog
Then I should be able to find it in the catalog
153. Feature: Adding new movies
In order to sell more movies
As an online movie seller
I want to be able to add movies to the catalog
Scenario: Adding movies
Given the following movie has just come out
| title | director | actors |
| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
When I add this movie to the catalog
Then I should be able to find it in the catalog
@Then("I should be able to find it in the catalog")
public void shouldBeAbleToFindMovieInCatalog() {
rest().given().contentType("application/json")
.get("/movies/{movieId}", movieId)
.then().statusCode(200)
.and().body("title", equalTo(newMovie.getTitle()))
.and().body("director", equalTo(newMovie.getDirector()));
}
154. Feature: Adding new movies
In order to sell more movies
As an online movie seller
I want to be able to add movies to the catalog
Scenario: Adding movies
Given the following movie has just come out
| title | director | actors |
| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
When I add this movie to the catalog
Then I should be able to find it in the catalog
@Then("I should be able to find it in the catalog")
public void shouldBeAbleToFindMovieInCatalog() {
rest().given().contentType("application/json")
.get("/movies/{movieId}", movieId)
.then().statusCode(200)
.and().body("title", equalTo(newMovie.getTitle()))
.and().body("director", equalTo(newMovie.getDirector()));
}
Rest Assured + Serenity
155. Feature: Adding new movies
In order to sell more movies
As an online movie seller
I want to be able to add movies to the catalog
Scenario: Adding movies
Given the following movie has just come out
| title | director | actors |
| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
When I add this movie to the catalog
Then I should be able to find it in the catalog
@Then("I should be able to find it in the catalog")
public void shouldBeAbleToFindMovieInCatalog() {
rest().given().contentType("application/json")
.get("/movies/{movieId}", movieId)
.then().statusCode(200)
.and().body("title", equalTo(newMovie.getTitle()))
.and().body("director", equalTo(newMovie.getDirector()));
}
162. Testing REST services with Rest-Assured
given().contentType("application/json")
.content(newMovie)
.post("/movies")
.then().statusCode(200)
.and().extract().jsonPath().getString("id");
Posting data
163. Testing REST services with Rest-Assured
Movie matchingMovie
= get("/movies/findByTitle/Gladiator").as(Movie.class);
164. Testing REST services with Rest-Assured
Movie matchingMovie
= get("/movies/findByTitle/Gladiator").as(Movie.class);
Convert responses to Java objects
165. Testing REST services with Rest-Assured
given().param("title","Unknown").
when().get("/movies/search").
then().statusCode(404);
166. Testing REST services with Rest-Assured
given().param("title","Unknown").
when().get("/movies/search").
then().statusCode(404);
Check for errors
185. MovieRepository repository
def artistService
def setup() {
repository = Mock(MovieRepository)
artistService = new ArtistService(movieRepository: repository)
}
def "should build actor details from films the artist has acted in and has directed"() {
given: "Clint Eastwood has directed some films"
repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
and: "Clint Eastwood has starred in some films"
repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
when:
def artistDetails = artistService.findArtistByName("Clint Eastwood")
then:
artistDetails.isPresent()
and:
artistDetails.get().name == "Clint Eastwood" &&
artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
}
186. MovieRepository repository
def artistService
def setup() {
repository = Mock(MovieRepository)
artistService = new ArtistService(movieRepository: repository)
}
def "should build actor details from films the artist has acted in and has directed"() {
given: "Clint Eastwood has directed some films"
repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
and: "Clint Eastwood has starred in some films"
repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
when:
def artistDetails = artistService.findArtistByName("Clint Eastwood")
then:
artistDetails.isPresent()
and:
artistDetails.get().name == "Clint Eastwood" &&
artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
}
Mocked repositories
187. MovieRepository repository
def artistService
def setup() {
repository = Mock(MovieRepository)
artistService = new ArtistService(movieRepository: repository)
}
def "should build actor details from films the artist has acted in and has directed"() {
given: "Clint Eastwood has directed some films"
repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
and: "Clint Eastwood has starred in some films"
repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
when:
def artistDetails = artistService.findArtistByName("Clint Eastwood")
then:
artistDetails.isPresent()
and:
artistDetails.get().name == "Clint Eastwood" &&
artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
}
Call the service
188. MovieRepository repository
def artistService
def setup() {
repository = Mock(MovieRepository)
artistService = new ArtistService(movieRepository: repository)
}
def "should build actor details from films the artist has acted in and has directed"() {
given: "Clint Eastwood has directed some films"
repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
and: "Clint Eastwood has starred in some films"
repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
when:
def artistDetails = artistService.findArtistByName("Clint Eastwood")
then:
artistDetails.isPresent()
and:
artistDetails.get().name == "Clint Eastwood" &&
artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
}
Check the outcomes
189. MovieRepository repository
def artistService
def setup() {
repository = Mock(MovieRepository)
artistService = new ArtistService(movieRepository: repository)
}
def "should build actor details from films the artist has acted in and has directed"() {
given: "Clint Eastwood has directed some films"
repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
and: "Clint Eastwood has starred in some films"
repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
when:
def artistDetails = artistService.findArtistByName("Clint Eastwood")
then:
artistDetails.isPresent()
and:
artistDetails.get().name == "Clint Eastwood" &&
artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
}
193. 65
Scenario: Adding movies
Given the following movie has just come out
| title | director | actors |
| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
When I add this movie to the catalog
Then I should be able to find it in the catalog
Executable Specifications
Automated tests Living documentation
201. 70
@RequestMapping(method = GET)
@ApiOperation("List all the movies in the catalog")
public List<Movie> findAll() {
return repository.findAll();
}
@RequestMapping(method = POST)
@ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")
public Movie add(@RequestBody Movie newMovie) {
return repository.save(newMovie);
}
@RequestMapping(value = "/{id}", method = DELETE)
@ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")
public void delete(@PathVariable String id) {
repository.delete(id);
}
Springfox
Some annotations…
Swagger and Spring Boot
202. 70
@RequestMapping(method = GET)
@ApiOperation("List all the movies in the catalog")
public List<Movie> findAll() {
return repository.findAll();
}
@RequestMapping(method = POST)
@ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")
public Movie add(@RequestBody Movie newMovie) {
return repository.save(newMovie);
}
@RequestMapping(value = "/{id}", method = DELETE)
@ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")
public void delete(@PathVariable String id) {
repository.delete(id);
}
Springfox
Some annotations…
Swagger and Spring Boot
203. 70
@RequestMapping(method = GET)
@ApiOperation("List all the movies in the catalog")
public List<Movie> findAll() {
return repository.findAll();
}
@RequestMapping(method = POST)
@ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")
public Movie add(@RequestBody Movie newMovie) {
return repository.save(newMovie);
}
@RequestMapping(value = "/{id}", method = DELETE)
@ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")
public void delete(@PathVariable String id) {
repository.delete(id);
}
Springfox
Some annotations…
Swagger and Spring Boot
204. 70
@RequestMapping(method = GET)
@ApiOperation("List all the movies in the catalog")
public List<Movie> findAll() {
return repository.findAll();
}
@RequestMapping(method = POST)
@ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")
public Movie add(@RequestBody Movie newMovie) {
return repository.save(newMovie);
}
@RequestMapping(value = "/{id}", method = DELETE)
@ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")
public void delete(@PathVariable String id) {
repository.delete(id);
}
Springfox
Some annotations…
Swagger and Spring Boot
205. 71
Springfox
@EnableAutoConfiguration
@EnableSwagger2
public class MovieServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MovieServiceApplication.class, args);
}
@Bean
public Docket moviesApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.pathMapping("/")
.directModelSubstitute(LocalDate.class, String.class)
.genericModelSubstitutes(ResponseEntity.class);
}
} Some configuration…
Swagger and Spring Boot
210. An example with Spring Actuator
@Component
public class CatalogHealth implements HealthIndicator {
@Autowired
MovieRepository movieRepository;
@Override
public Health health() {
return (isCatalogStocked()) ?
Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build()
: Health.down().build();
}
private boolean isCatalogStocked() {
return (movieRepository.count() > 0);
}
}
211. An example with Spring Actuator
@Component
public class CatalogHealth implements HealthIndicator {
@Autowired
MovieRepository movieRepository;
@Override
public Health health() {
return (isCatalogStocked()) ?
Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build()
: Health.down().build();
}
private boolean isCatalogStocked() {
return (movieRepository.count() > 0);
}
}
A Spring Actuator Health Check
212. An example with Spring Actuator
@Component
public class CatalogHealth implements HealthIndicator {
@Autowired
MovieRepository movieRepository;
@Override
public Health health() {
return (isCatalogStocked()) ?
Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build()
: Health.down().build();
}
private boolean isCatalogStocked() {
return (movieRepository.count() > 0);
}
}
A Spring Actuator Health Check
Custom logic to decide if the app is working
213. An example with Spring Actuator
@Component
public class MovieTransactionHealth implements HealthIndicator {
@Autowired
MovieController movieController;
@Override
public Health health() {
return Health.status(transactionStatus()).build();
}
private Status transactionStatus() {
try {
Movie movie = new Movie("TEST title", "TEST description", "TEST director",
ImmutableList.of("TEST actor"));
Movie reloadedMovie = movieController.add(movie);
movieController.delete(reloadedMovie.getId());
return Status.UP;
} catch (Throwable e) {
return new Status("DOWN", e.toString());
}
}
}
214. An example with Spring Actuator
@Component
public class MovieTransactionHealth implements HealthIndicator {
@Autowired
MovieController movieController;
@Override
public Health health() {
return Health.status(transactionStatus()).build();
}
private Status transactionStatus() {
try {
Movie movie = new Movie("TEST title", "TEST description", "TEST director",
ImmutableList.of("TEST actor"));
Movie reloadedMovie = movieController.add(movie);
movieController.delete(reloadedMovie.getId());
return Status.UP;
} catch (Throwable e) {
return new Status("DOWN", e.toString());
}
}
}
More complex custom logic
215. An example with Spring Actuator
@Component
public class MovieTransactionHealth implements HealthIndicator {
@Autowired
MovieController movieController;
@Override
public Health health() {
return Health.status(transactionStatus()).build();
}
private Status transactionStatus() {…}
}
@Component
public class CatalogHealth implements HealthIndicator {
@Autowired
MovieRepository movieRepository;
@Override
public Health health() {
return (isCatalogStocked()) ?
Health.status(new Status("UP", "Movie count: " +
movieRepository.count())).build()
: Health.down().build();
}
private boolean isCatalogStocked() {…}
}
216. Try all this out at home!
Install Gradle
Install MongoDB
Clone the repowakaleo/movie-service