Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Spring MVC Integration Testing
Search
Oliver Drotbohm
August 15, 2013
Programming
260
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Spring MVC Integration Testing
Slide of my talk at JUG Ostfalen about Spring MVC integration testing
Oliver Drotbohm
August 15, 2013
More Decks by Oliver Drotbohm
See All by Oliver Drotbohm
What's new in Spring Modulith?
olivergierke
1
380
Domain-centric? Why Hexagonal and Onion Architecture Are Answers to the Wrong Question
olivergierke
4
2.2k
It Takes Two to Tango – Designing Module Interactions in Modulithic Spring Applications
olivergierke
5
860
Bottom-Up Architecture – Bridging the Achitecture Code Gap
olivergierke
4
1.1k
Spring Modulith – A Deep Dive
olivergierke
9
6k
Spring for the Architecturally Curious Developer
olivergierke
5
2k
Spring Boot 3 & Spring Framework 6
olivergierke
4
2.2k
Architecturally-evident Java Applications with jMolecules
olivergierke
9
3.2k
A Deep Dive into Spring Application Events
olivergierke
12
3.6k
Other Decks in Programming
See All in Programming
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
210
Agents on Rails - Rails at Scale 2026
irinanazarova
0
560
最近”作らせてる” ローカルAIアプリの話
akit37
0
470
Jetpack Compose Mechanisms
skydoves
3
820
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
410
dotNET_vulnclicker_intro.pdf
deka_morita
0
140
sbt 2.0: takeoff
eed3si9n
0
160
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
370
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
2
560
Railsバージョンを4倍にした話
optim
0
360
JIS keyboard support in Omarchy
lef237
0
110
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
430
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
How to train your dragon (web standard)
notwaldorf
96
6.9k
Docker and Python
trallard
47
4.2k
Fireside Chat
paigeccino
43
4.1k
Side Projects
sachag
456
43k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
Being A Developer After 40
akosma
92
590k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
300
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
450
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3.1k
Designing Powerful Visuals for Engaging Learning
tmiket
1
610
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
570
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