diff --git a/testing-modules/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml
index 5d3cac4aa3..cd342ccd11 100644
--- a/testing-modules/rest-assured/pom.xml
+++ b/testing-modules/rest-assured/pom.xml
@@ -19,6 +19,10 @@
org.springframework.boot
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-starter-json
+
org.springframework.boot
spring-boot-starter-test
@@ -97,7 +101,7 @@
joda-time
- joda-time
+ joda-time
@@ -143,15 +147,6 @@
wiremock
${wiremock.version}
-
- io.rest-assured
- rest-assured
- test
-
-
- io.rest-assured
- json-schema-validator
-
com.github.fge
json-schema-validator
@@ -167,6 +162,23 @@
commons-collections
${commons-collections.version}
+
+
+
+ io.rest-assured
+ rest-assured
+ test
+
+
+ io.rest-assured
+ spring-mock-mvc
+ test
+
+
+ io.rest-assured
+ json-schema-validator
+ test
+
diff --git a/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/Course.java b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/Course.java
new file mode 100644
index 0000000000..ac958b3239
--- /dev/null
+++ b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/Course.java
@@ -0,0 +1,17 @@
+package com.baeldung.restassured.learner;
+
+class Course {
+
+ private String code;
+
+ public Course() {
+ }
+
+ Course(String code) {
+ this.code = code;
+ }
+
+ String getCode() {
+ return code;
+ }
+}
diff --git a/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseController.java b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseController.java
new file mode 100644
index 0000000000..f4a3f56608
--- /dev/null
+++ b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseController.java
@@ -0,0 +1,31 @@
+package com.baeldung.restassured.learner;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Collection;
+
+import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
+
+@RestController
+@RequestMapping(path = "/courses")
+public class CourseController {
+
+ private final CourseService courseService;
+
+ public CourseController(CourseService courseService) {
+ this.courseService = courseService;
+ }
+
+ @GetMapping(produces = APPLICATION_JSON_UTF8_VALUE)
+ public Collection getCourses() {
+ return courseService.getCourses();
+ }
+
+ @GetMapping(path = "/{code}", produces = APPLICATION_JSON_UTF8_VALUE)
+ public Course getCourse(@PathVariable String code) {
+ return courseService.getCourse(code);
+ }
+}
diff --git a/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseControllerExceptionHandler.java b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseControllerExceptionHandler.java
new file mode 100644
index 0000000000..b17e95c31c
--- /dev/null
+++ b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseControllerExceptionHandler.java
@@ -0,0 +1,18 @@
+package com.baeldung.restassured.learner;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+@ControllerAdvice(assignableTypes = CourseController.class)
+public class CourseControllerExceptionHandler extends ResponseEntityExceptionHandler {
+
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ @ExceptionHandler(CourseNotFoundException.class)
+ @SuppressWarnings("ThrowablePrintedToSystemOut")
+ public void handleCourseNotFoundException(CourseNotFoundException cnfe) {
+ System.out.println(cnfe);
+ }
+}
diff --git a/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseNotFoundException.java b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseNotFoundException.java
new file mode 100644
index 0000000000..dc1a3f796d
--- /dev/null
+++ b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseNotFoundException.java
@@ -0,0 +1,8 @@
+package com.baeldung.restassured.learner;
+
+class CourseNotFoundException extends RuntimeException {
+
+ CourseNotFoundException(String code) {
+ super(code);
+ }
+}
diff --git a/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseService.java b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseService.java
new file mode 100644
index 0000000000..11508ab9ba
--- /dev/null
+++ b/testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseService.java
@@ -0,0 +1,27 @@
+package com.baeldung.restassured.learner;
+
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Service
+class CourseService {
+
+ private static final Map COURSE_MAP = new ConcurrentHashMap<>();
+
+ static {
+ Course wizardry = new Course("Wizardry");
+ COURSE_MAP.put(wizardry.getCode(), wizardry);
+ }
+
+ Collection getCourses() {
+ return COURSE_MAP.values();
+ }
+
+ Course getCourse(String code) {
+ return Optional.ofNullable(COURSE_MAP.get(code)).orElseThrow(() -> new CourseNotFoundException(code));
+ }
+}
diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/learner/CourseControllerIntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/learner/CourseControllerIntegrationTest.java
new file mode 100644
index 0000000000..5e36cd169b
--- /dev/null
+++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/learner/CourseControllerIntegrationTest.java
@@ -0,0 +1,40 @@
+package com.baeldung.restassured.learner;
+
+import static io.restassured.module.mockmvc.RestAssuredMockMvc.given;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+import static org.springframework.http.HttpStatus.NOT_FOUND;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.context.WebApplicationContext;
+
+import io.restassured.module.mockmvc.RestAssuredMockMvc;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = RANDOM_PORT)
+public class CourseControllerIntegrationTest {
+
+ @Autowired
+ private WebApplicationContext webApplicationContext;
+
+ @Before
+ public void initialiseRestAssuredMockMvcWebApplicationContext() {
+ RestAssuredMockMvc.webAppContextSetup(webApplicationContext);
+ }
+
+ @Test
+ public void givenNoMatchingCourseCodeWhenGetCourseThenRespondWithStatusNotFound() {
+ String nonMatchingCourseCode = "nonMatchingCourseCode";
+
+ given()
+ .when()
+ .get("/courses/" + nonMatchingCourseCode)
+ .then()
+ .log().ifValidationFails()
+ .statusCode(NOT_FOUND.value());
+ }
+}
diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/learner/CourseControllerUnitTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/learner/CourseControllerUnitTest.java
new file mode 100644
index 0000000000..2a795e2b0b
--- /dev/null
+++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/learner/CourseControllerUnitTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.restassured.learner;
+
+import io.restassured.module.mockmvc.RestAssuredMockMvc;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.Collections;
+
+import static io.restassured.http.ContentType.JSON;
+import static io.restassured.module.mockmvc.RestAssuredMockMvc.given;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.when;
+import static org.springframework.http.HttpStatus.NOT_FOUND;
+import static org.springframework.http.HttpStatus.OK;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CourseControllerUnitTest {
+
+ @Mock
+ private CourseService courseService;
+ @InjectMocks
+ private CourseController courseController;
+ @InjectMocks
+ private CourseControllerExceptionHandler courseControllerExceptionHandler;
+
+ @Before
+ public void initialiseRestAssuredMockMvcStandalone() {
+ RestAssuredMockMvc.standaloneSetup(courseController, courseControllerExceptionHandler);
+ }
+
+ @Test
+ public void givenNoExistingCoursesWhenGetCoursesThenRespondWithStatusOkAndEmptyArray() {
+ when(courseService.getCourses()).thenReturn(Collections.emptyList());
+
+ given()
+ .when()
+ .get("/courses")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(OK.value())
+ .contentType(JSON)
+ .body(is(equalTo("[]")));
+ }
+
+ @Test
+ public void givenNoMatchingCoursesWhenGetCoursesThenRespondWithStatusNotFound() {
+ String nonMatchingCourseCode = "nonMatchingCourseCode";
+
+ when(courseService.getCourse(nonMatchingCourseCode)).thenThrow(new CourseNotFoundException(nonMatchingCourseCode));
+
+ given()
+ .when()
+ .get("/courses/" + nonMatchingCourseCode)
+ .then()
+ .log().ifValidationFails()
+ .statusCode(NOT_FOUND.value());
+ }
+}