Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Spring MVC Integration Testing
Search
Oliver Drotbohm
August 15, 2013
Programming
2
240
Spring MVC Integration Testing
Slide of my talk at JUG Ostfalen about Spring MVC integration testing
Oliver Drotbohm
August 15, 2013
Tweet
Share
More Decks by Oliver Drotbohm
See All by Oliver Drotbohm
It Takes Two to Tango – Designing Module Interactions in Modulithic Spring Applications
olivergierke
5
720
Bottom-Up Architecture – Bridging the Achitecture Code Gap
olivergierke
4
950
Spring Modulith – A Deep Dive
olivergierke
8
4.5k
Spring for the Architecturally Curious Developer
olivergierke
5
1.8k
Spring Boot 3 & Spring Framework 6
olivergierke
4
2k
Architecturally-evident Java Applications with jMolecules
olivergierke
9
2.9k
A Deep Dive into Spring Application Events
olivergierke
12
3.3k
Building Better Monoliths – Modulithic Applications with Spring Boot
olivergierke
4
970
Spring HATEOAS – Hypermedia APIs with Spring
olivergierke
1
750
Other Decks in Programming
See All in Programming
Namespace and Its Future
tagomoris
6
700
速いWebフレームワークを作る
yusukebe
5
1.7k
サーバーサイドのビルド時間87倍高速化
plaidtech
PRO
0
710
実用的なGOCACHEPROG実装をするために / golang.tokyo #40
mazrean
1
240
開発チーム・開発組織の設計改善スキルの向上
masuda220
PRO
18
10k
TanStack DB ~状態管理の新しい考え方~
bmthd
2
490
奥深くて厄介な「改行」と仲良くなる20分
oguemon
1
460
print("Hello, World")
eddie
1
510
「手軽で便利」に潜む罠。 Popover API を WCAG 2.2の視点で安全に使うには
taitotnk
0
780
私の後悔をAWS DMSで解決した話
hiramax
4
200
アプリの "かわいい" を支えるアニメーションツールRiveについて
uetyo
0
210
パッケージ設計の黒魔術/Kyoto.go#63
lufia
3
430
Featured
See All Featured
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.1k
Raft: Consensus for Rubyists
vanstee
140
7.1k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
How STYLIGHT went responsive
nonsquared
100
5.8k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Code Reviewing Like a Champion
maltzj
525
40k
The Art of Programming - Codeland 2020
erikaheidi
55
13k
RailsConf 2023
tenderlove
30
1.2k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
Gamification - CAS2011
davidbonilla
81
5.4k
Visualization
eitanlees
148
16k
Transcript
Spring MVC Integration Testing Oliver Gierke
Oliver Gierke Spring Data Core/JPA/MongoDB JPA 2.1 Expert Group
[email protected]
www.olivergierke.de olivergierke
We want to build quality software!
We want to build quality software!
Testable software is quality software!
Testable software is quality software!
Only testable software can be changed easily.
Only testable software can be changed easily.
Testing should cause as little overhead as possible.
Testing should cause as little overhead as possible.
Unit testing VS. Integration testing
Side track: Spring MVC
Spring MVC Infrastructure HTTP / Servlet API Controller implementations Application
services
Spring MVC Infrastructure HTTP / Servlet API Controller implementations Application
services
Spring MVC Infrastructure HTTP / Servlet API Controller implementations Application
services
@Controller class PersonController { @RequestMapping(value = "/people", method = GET)
HttpEntity<List<Person>> showPeople() { List<Person> result = people.findAll(); return new ResponseEntity<>(result, HttpStatus.OK); } @RequestMapping(value = "/people", method = POST) HttpEntity<Void> create(@RequestBody Person person) { Person result = people.create(person); HttpHeaders = new HttpHeaders(); headers.setLocation(…); return new ResponseEntity<>(headers, HttpStatus.CREATED); } } REST
@Controller class PersonController { @RequestMapping(value = "/people", method = GET)
String showPeople(Model model) { model.put("people", people.findAll()); return "people"; } @RequestMapping(value = "/people", method = POST) String create(@ModelAttribute Person person, Model model) { Person result = people.create(person); // Add success or error message to model return "people"; } } View resolution
Unit testable Mock dependencies Call methods Verify outcome
What about the web layer overall?
Left untested Servlet API setup Spring MVC setup Request mapping
Custom extensions
Spring MVC HTTP / Servlet API Controller implementations Application services
Extensions
The 2 runtimes approach
Test process Use embedded container Bootstrap before tests Execute tests
Shutdown after tests
Application in embedded Jetty / Tomcat Test execution JVM JVM
Application in embedded Jetty / Tomcat Test execution JVM JVM
Environment implications Separate process Port required in environment Build setup
tweaks
Testing implications Data setup Transaction management
Works, but has its issues.
The integrated runtime approach
Test Context Framework Bootstraps ApplicationContexts Transaction management Context caching Extensible
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:application-context.xml") @Transactional public class SampleIntegrationTests { @Autowired Dependency dependency;
@Test public void myTest() { // Implement test here } } Sample test case
Test Context Framework ApplicationContext
Test Context Framework ApplicationContext MockMVC
Mock MVC Integrates with Test Framework API to build "requests"
API to define result expectations
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration("classpath:application-context.xml") public class SampleIntegrationTests { @Autowired WebApplicationContext context;
MockMvc mvc; @Before public void setUp() { this.mvc = MockMvcBuilders. webAppContextSetup(this.context).build(); } } MVC testing
import static org.sfw.….MockMvcRequestBuilders.*; import static org.sfw.….MockMvcResultMatchers.*; public class SampleIntegrationTests {
@Test public void setUp() { this.mvc.perform(get("/accounts/1") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentType("application/json")) .andExpect(jsonPath("$.name").value("Lee")); } } MVC testing
Setup Bootstrap from WebApplicationContext Register Servlet API artifacts Support for
individual controllers
Building requests Execute HTTP methods Define request parameters / payload
HTTP headers
Define expectations Response status, header, body XPath / JSONPath
DEMO
Recap
In-container MVC testing
Benefits No infrastructure implications No build tweaks necessary Standard test
transaction handling Context caching
Client side REST tests
import static org.sfw.….MockRestResponseCreators.*; RestTemplate restTemplate = new RestTemplate(); MockRestServiceServer mockServer
= MockRestServiceServer.createServer(restTemplate); mockServer.expect(requestTo("/greeting")) .andRespond(withSuccess("Hello world!", "text/plain")); // use RestTemplate mockServer.verify(); Mock REST server
Questions?
Resources Reference documentation Spring RESTBucks