Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
giuseppe-trisciuoglio avatar

Unit Test Controller Layer

  • 1.7k installs
  • 311 repo stars
  • Updated June 22, 2026
  • giuseppe-trisciuoglio/developer-kit

MockMvc-based patterns for unit testing Spring REST controllers with mocked dependencies, validating HTTP semantics without full application context.

About

Provides patterns for unit testing @RestController and @Controller classes with MockMvc, covering request/response handling, HTTP status codes, parameter binding, validation, content negotiation, headers, and exception handling. Developers use this when testing web layer endpoints in isolation to verify REST controllers work correctly without full application context. Key workflows include setting up standalone MockMvc, mocking service dependencies, testing all HTTP methods (GET/POST/PUT/DELETE), validating JSON responses with JsonPath, testing validation errors and error codes (404/400/500), and verifying request/response headers and content negotiation.

  • MockMvc standaloneSetup() for isolated controller testing without full Spring context
  • Mocking service dependencies with @Mock/@InjectMocks to test controller logic only
  • JsonPath assertions for validating JSON response structure, content, and nested fields
  • Full HTTP method coverage: GET/POST/PUT/PATCH/DELETE with appropriate status code verification
  • Error scenario testing for validation errors (400), not found (404), and unauthorized (401)

Unit Test Controller Layer by the numbers

  • 1,662 all-time installs (skills.sh)
  • +55 installs in the week ending Jul 28, 2026 (Skillselion tracking)
  • Ranked #435 of 2,184 Testing & QA skills by installs in the Skillselion catalog
  • Security screen: MEDIUM risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
At a glance

unit-test-controller-layer capabilities & compatibility

Capabilities
controller testing · http request mocking · response validation · status code verification · exception testing · header testing
Use cases
testing · code review · api development
Platforms
macOS · Windows · Linux
Runs
Runs locally
Pricing
Free
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill unit-test-controller-layer

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1.7k
repo stars311
Security audit3 / 3 scanners passed
Last updatedJune 22, 2026
Repositorygiuseppe-trisciuoglio/developer-kit

What it does

Unit test Spring REST controllers in isolation using MockMvc to validate HTTP request/response handling, status codes, and exception scenarios.

Who is it for?

Spring REST controller testing, API endpoint validation, isolated web layer testing, HTTP status code verification, request/response mapping.

Skip if: Integration tests, end-to-end testing, testing business logic (belongs in service layer), testing with real databases or external services.

When should I use this skill?

Writing unit tests for @RestController or @Controller classes, testing HTTP methods (GET/POST/PUT/DELETE), validating request/response contracts, testing error handling and edge cases.

What you get

Developer can write focused controller unit tests that validate HTTP behavior, error scenarios, and response structure for all REST endpoints.

  • Controller test class with @ExtendWith(MockitoExtension.class)
  • setUp() method initializing MockMvc with standaloneSetup()
  • Multiple test methods covering happy path and error scenarios

By the numbers

  • Covers 6+ HTTP status code scenarios (200, 201, 204, 400, 404, 500)
  • Includes 11 code examples demonstrating different test patterns

Files

SKILL.mdMarkdownGitHub ↗

Unit Testing REST Controllers with MockMvc

Overview

Provides patterns for unit testing @RestController and @Controller classes using MockMvc. Covers request/response handling, HTTP status codes, request parameter binding, validation, content negotiation, response headers, and exception handling with mocked service dependencies.

When to Use

Use for: controller tests, API endpoint testing, Spring MVC tests, mock HTTP requests, unit testing web layer endpoints, verifying REST controllers in isolation.

Instructions

1. Setup standalone MockMvc: MockMvcBuilders.standaloneSetup(controller) for isolated testing 2. Mock service dependencies: Use @Mock for all services, @InjectMocks for the controller 3. Test HTTP methods: GET, POST, PUT, PATCH, DELETE with correct status codes 4. Validate responses: JsonPath assertions for JSON, content matchers for body 5. Test validation: Send invalid input, verify 400 status with error details 6. Test errors: Verify 404, 400, 401, 403, 500 for appropriate conditions 7. Validate headers: Both request (Authorization) and response headers 8. Test content negotiation: Different Accept and Content-Type headers

Validation Workflow

Run test → If fails: add .andDo(print()) → Check actual vs expected → Fix assertion

Examples

Maven / Gradle Dependencies

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

Basic Pattern: GET Endpoint

import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@ExtendWith(MockitoExtension.class)
class UserControllerTest {

  @Mock
  private UserService userService;

  @InjectMocks
  private UserController userController;

  private MockMvc mockMvc;

  @BeforeEach
  void setUp() {
    mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
  }

  @Test
  void shouldReturnAllUsers() throws Exception {
    List<UserDto> users = List.of(new UserDto(1L, "Alice"), new UserDto(2L, "Bob"));
    when(userService.getAllUsers()).thenReturn(users);

    mockMvc.perform(get("/api/users"))
      .andExpect(status().isOk())
      .andExpect(jsonPath("$[0].id").value(1))
      .andExpect(jsonPath("$[0].name").value("Alice"));

    verify(userService, times(1)).getAllUsers();
  }

  @Test
  void shouldReturn404WhenUserNotFound() throws Exception {
    when(userService.getUserById(999L))
      .thenThrow(new UserNotFoundException("User not found"));

    mockMvc.perform(get("/api/users/999"))
      .andExpect(status().isNotFound());

    verify(userService).getUserById(999L);
  }
}

POST: Create Resource

@Test
void shouldCreateUserAndReturn201() throws Exception {
  UserDto createdUser = new UserDto(1L, "Alice", "alice@example.com");
  when(userService.createUser(any())).thenReturn(createdUser);

  mockMvc.perform(post("/api/users")
      .contentType("application/json")
      .content("{\"name\":\"Alice\",\"email\":\"alice@example.com\"}"))
    .andExpect(status().isCreated())
    .andExpect(jsonPath("$.id").value(1))
    .andExpect(jsonPath("$.name").value("Alice"));

  verify(userService).createUser(any(UserCreateRequest.class));
}

PUT: Update Resource

@Test
void shouldUpdateUserAndReturn200() throws Exception {
  UserDto updatedUser = new UserDto(1L, "Updated");
  when(userService.updateUser(eq(1L), any())).thenReturn(updatedUser);

  mockMvc.perform(put("/api/users/1")
      .contentType("application/json")
      .content("{\"name\":\"Updated\"}"))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$.name").value("Updated"));

  verify(userService).updateUser(eq(1L), any());
}

DELETE: Remove Resource

@Test
void shouldDeleteUserAndReturn204() throws Exception {
  doNothing().when(userService).deleteUser(1L);

  mockMvc.perform(delete("/api/users/1"))
    .andExpect(status().isNoContent());

  verify(userService).deleteUser(1L);
}

Query Parameters

@Test
void shouldFilterUsersByName() throws Exception {
  when(userService.searchUsers("Alice")).thenReturn(List.of(new UserDto(1L, "Alice")));

  mockMvc.perform(get("/api/users/search").param("name", "Alice"))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$[0].name").value("Alice"));

  verify(userService).searchUsers("Alice");
}

Path Variables

@Test
void shouldGetUserByIdFromPath() throws Exception {
  when(userService.getUserById(123L)).thenReturn(new UserDto(123L, "Alice"));

  mockMvc.perform(get("/api/users/{id}", 123L))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$.id").value(123));
}

Validation Errors (400)

@Test
void shouldReturn400WhenRequestBodyInvalid() throws Exception {
  mockMvc.perform(post("/api/users")
      .contentType("application/json")
      .content("{\"name\":\"\"}"))
    .andExpect(status().isBadRequest())
    .andExpect(jsonPath("$.errors").isArray());
}

Response Headers

@Test
void shouldReturnCustomHeaders() throws Exception {
  when(userService.getAllUsers()).thenReturn(List.of());

  mockMvc.perform(get("/api/users"))
    .andExpect(status().isOk())
    .andExpect(header().exists("X-Total-Count"))
    .andExpect(header().string("X-Total-Count", "0"));
}

Authorization Header

@Test
void shouldRequireAuthorizationHeader() throws Exception {
  mockMvc.perform(get("/api/users"))
    .andExpect(status().isUnauthorized());

  mockMvc.perform(get("/api/users").header("Authorization", "Bearer token"))
    .andExpect(status().isOk());
}

Content Negotiation

@Test
void shouldReturnJsonWhenAcceptHeaderIsJson() throws Exception {
  when(userService.getUserById(1L)).thenReturn(new UserDto(1L, "Alice"));

  mockMvc.perform(get("/api/users/1").accept("application/json"))
    .andExpect(status().isOk())
    .andExpect(content().contentType("application/json"));
}

Best Practices

  • Use standaloneSetup() for isolated controller testing
  • Mock service layer — controllers handle HTTP, services handle business logic
  • Verify mock interactions: verify(service).method(args)
  • Test happy path AND error scenarios (404, 400, 500)
  • Use jsonPath() for fluent JSON assertions
  • One focused assertion per test method

Constraints and Warnings

  • Controller tests verify HTTP handling only — not full request flow
  • standaloneSetup() may not support @Validated without full context
  • JsonPath requires valid JSON in response body
  • @PreAuthorize/@Secured need additional setup — consider separate security tests
  • File uploads require MockMultipartFile

References

Related skills

Forks & variants (1)

Unit Test Controller Layer has 1 known copy in the catalog totaling 21 installs. They canonicalize to this original listing.

How it compares

Pick this for isolated Spring controller unit tests with MockMvc rather than full-stack integration or repository-layer coverage.

FAQ

Should I use standaloneSetup() or WebApplicationContext for controller tests?

Use standaloneSetup() for isolated unit tests of a single controller with mocked dependencies. WebApplicationContext is for integration tests requiring full Spring context.

How do I assert JSON response content in MockMvc tests?

Use jsonPath() matcher with dot notation: .andExpect(jsonPath("$.fieldName").value(expectedValue)) for single fields or .andExpect(jsonPath("$[0].id").value(1)) for arrays.

How do I test validation errors and 400 Bad Request responses?

Send invalid request body (e.g., empty required field) and assert .andExpect(status().isBadRequest()) with jsonPath to verify error details in response.

Is Unit Test Controller Layer safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

Testing & QAtestingbackend

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.