Skip to content
Ameen Abozaid
JNR-016

Spring testing basics

  • 7 Lessons
  • 3 h practice (estimate)
On this page 8 topics

Overview

Topics

  • Spring test context
  • test slices
  • Mockito
  • MockMvc

Learn first

3 h of practice (estimate)

Learning outcomes

  1. Unit-test a service without Spring by passing collaborators to its constructor.
  2. Test a controller with @WebMvcTest and MockMvc, including validation and error responses.
  3. Use a basic Mockito mock for the service under a controller test.
  4. Explain the cost of @SpringBootTest and when a slice is enough.

Lessons

  1. 01Testing pyramid for Spring apps
  2. 02Plain unit tests for services
  3. 03Mockito in five minutes
  4. 04@WebMvcTest and MockMvc
  5. 05@SpringBootTest and context caching
  6. 06Demo: test-driving a controller with @WebMvcTest
  7. 07Demo: slice vs full-context tests, timed

Lab and exercises

Lab

JNR-016-LAB1 · Test the products feature

Outcomes: 1–4 · Time: ~3 h

  1. Write unit tests for ProductService using a fake or in-memory repository (found, not found, rule violation).
  2. Write @WebMvcTest tests for ProductController: GET /products/{id} success, POST /products validation failure, and not found.
  3. Mock the service with Mockito inside the slice tests.
  4. Assert the JSON body and the Problem Details shape, not only the status.
  5. Add one @SpringBootTest smoke test and record the run times of both kinds.

Acceptance: tests run in seconds; no full context in controller tests; every test asserts the body or behavior.

Exercises (assessment: write the missing tests for a provided controller)

IDOutcomeTask
JNR-016-EX011Unit-test PricingService with constructor-passed fakes (no annotations).
JNR-016-EX022Write a MockMvc test for GET /products returning two items; assert the array length and a field.
JNR-016-EX032Write a MockMvc test where a blank name returns 400; assert the field error.
JNR-016-EX043Stub service.get(5) to throw NotFoundException and verify the 404 body; also verify the service call.
JNR-016-EX054Time a slice test versus a @SpringBootTest for the same endpoint; write two sentences on when each is right.
JNR-016-EX064Given a suite with eight @SpringBootTest classes, each with a different @MockitoBean, explain the slowness and propose a fix.
Show solutions
  • EX01 var service = new PricingService(fakeRates); assertThat(service.total(...)).isEqualByComparingTo("12.00");
  • EX02 mvc.perform(get("/products")).andExpect(status().isOk()).andExpect(jsonPath("$.length()").value(2)).andExpect(jsonPath("$[0].name").value("Pen"));
  • EX03 mvc.perform(post("/products").contentType(APPLICATION_JSON).content("{\"name\":\"\"}")).andExpect(status().isBadRequest()) plus a jsonPath check on the errors.
  • EX04 when(service.get(5)).thenThrow(new NotFoundException("Product",5)); then check the 404 and verify(service).get(5).
  • EX05 Slice: faster, tests the web layer only. Full context: slower, tests the wiring and everything together.
  • EX06 Each different mock creates a new cached context; reduce them by using slices, or share one configuration or base class.

Quiz

Outcomes: O1 plain unit tests · O2 @WebMvcTest and MockMvc · O3 basic Mockito · O4 slice vs full context.

A self-check for you: nothing is graded, saved or sent anywhere. Choose an answer, then check it. You can try again as often as you like.

  1. 1A service with constructor injection can be unit-tested by:O1
  2. 2Which test type should be the most numerous?O1
  3. 3@WebMvcTest loads:O2
  4. 4MockMvc is used to:O2
  5. 5For a controller validation test, assert:O2
  6. 6when(repo.findById(1L)).thenReturn(...) does what?O3
  7. 7What should you mock in a controller test?O3
  8. 8Asserting only the status code in a test is:O3
  9. 9@SpringBootTest is costly because:O4
  10. 10A new @MockitoBean or changed properties often:O4

Practical part

Six exercises JNR-016-EX01 to EX06 plus the lab. The assessment: write the missing tests for a provided controller (success, validation failure, not found). Pass: quiz at least 8/10, the three missing tests written and passing with body assertions, lab acceptance met.

Common mistakes

@SpringBootTest for everything; asserting only the status code.

Assessment

Write the missing tests for a provided controller.

Career relevance

Deepened in JNR-043 to JNR-047.

Type to search levels, phases, modules and lessons.