MockMvc Module
RECORDO
The Recordo MockMvc module empowers developers to streamline the testing of controllers using the MockMvc framework, offering two powerful mechanisms for testing flexibility:
API Client Interfaces
Developers can define an interface where they specify the API endpoints they want to test using standard Spring annotations. This intuitive approach simplifies the testing process, as Recordo handles the underlying logic. Developers only need to autowire this interface in their test classes.
Example Interface
@RecordoApiClient(interceptors = AuthInterceptor.class)
@RequestMapping("/users")
public interface UserApiClient {
@GetMapping("/{id}")
UserDto findById(@PathVariable int id);
@GetMapping("/{id}")
@ResponseStatus(HttpStatus.NOT_FOUND)
ErrorDto findById_NotFound(@PathVariable int id);
@GetMapping
Page<UserDto> findAll(@RequestParam("q") String query, Pageable pageable);
@PostMapping("/{id}/pic")
void uploadPic(@PathVariable int id, @RequestParam Request.File file);
@PostMapping
UserDto create(@RequestBody UserDto userDto);
@DeleteMapping("/{id}")
void delete(@PathVariable int id);
}
Usage Examples
@ExtendWith(RecordoExtension.class)
@WebMvcTest(UserController.class)
class UserControllerTest {
private final UserApiClient apiClient = Recordo.create(UserApiClient.class);
@Test
void should_find_by_id() {
// ...
UserDto user = apiClient.findById(1L);
// ...
}
@Test
void should_get_not_found_error() {
// ...
ErrorDto error = apiClient.findById_NotFound(1L);
// ...
}
@Test
void should_find_all() {
// ...
PageRequest pageRequest = PageRequest.of(0, 20, Sort.by(asc("name")));
Page<UserDto> users = apiClient.findAll("john", pageRequest);
// ...
}
@Test
void should_create_user(
@Read("/users/new_user.json") UserDto newUser
) {
// ...
UserDto createdUser = apiClient.create(newUser);
// ...
}
@Test
void should_upload_pic() {
// ...
Request.File file = Request.File.builder()
.name("pic.png")
.content(fileBytes)
.build();
apiClient.uploadPic(1L, file);
// ...
}
}
Test Parameters
Developers can declare necessary requests directly as parameters in their test methods, specifying the HTTP method, URI, request body, and other details. This approach provides fine-grained control over requests.
Annotation Parameters
value
String
Request path
headers
String[]
List of headers
expectedStatus
HttpStatus
Expected HTTP status (OK by default)
interceptors
Class<? extends RequestInterceptor>[]
List of request Interceptors
objectMapper
String
Name of ObjectMapper bean or test class field
Usage Examples
@Test
void shouldGetBooks(
@Get("/users/1/books?page=2") Page<Book> books
) {
// Perform test assertions using the retrieved books
// ...
}
@Test
void shouldGetNotFound(
@Get(value = "/users/1/books?page=2", expectedStatus = HttpStatus.NOT_FOUND) ErrorDto errorDto
) {
// ...
}
@Test
void shouldCreateBook(
@Post(value = "/books", expectedStatus = HttpStatus.CREATED) Request<Book> request
) {
// Create a book instance
Book book = ...
// Perform the request and retrieve the response
Response<Book> response = request.body(book).perform();
Book createdBook = response.getBody();
// Perform test assertions using the created book
// ...
}
@Test
void shouldUpdateBook(
@Put(value = "/books", body = @Content(file = "/book.json")) Book updatedBook
) {
// Perform test assertions using the updated book
// ...
}
@Test
void shouldDeleteBook(
@Delete(value = "/books/{id}", expectedStatus = HttpStatus.NO_CONTENT) Response<Void> response
) {
// Perform test assertions for successful deletion
// ...
}
Type Options
Developers have flexibility in choosing how they handle response and request types. Result Type Options offer a convenient way to interact with API responses for diverse testing scenarios.
1. Object Result Type (Page<Book>
, Book
)
Page<Book>
, Book
)Developers can directly retrieve the response body as an object, simplifying test assertions.
@GetMapping("/{id}")
UserDto findById(@PathVariable int id);
@Get("/users/1/books?page=2") Page<Book> books
2. Response Object (Response<Book>
, Response<Void>
)
Response<Book>
, Response<Void>
)Developers can declare the response type as an object to access detailed information such as status and headers.
@GetMapping("/{id}")
Response<UserDto> findById(@PathVariable int id);
@Get("/users/1/books?page=2") Response<Page<Book>> booksResponse
3. Request Object (Request<Book>
)
Request<Book>
)Developers can use the Request
type to perform additional customizations before executing the request.
@GetMapping("/{id}")
Request<UserDto> findById(@PathVariable int id);
@Get("/users/1/books?page=2") Request<Page<Book>> booksRequest
Last updated