From fda8a29eb62125705027748ff77fbfba7a2164c3 Mon Sep 17 00:00:00 2001 From: Trevor Gowing Date: Mon, 25 Mar 2019 15:29:04 +0200 Subject: [PATCH] BAEL-2736 rest assured spring mock mvc (#6466) * Include rest-assured.spring-mock-mvc dependency BAEL-2736 * Rest Assured Spring Mock MVC Tests BAEL-2736 --- testing-modules/rest-assured/pom.xml | 32 +++++++--- .../baeldung/restassured/learner/Course.java | 17 +++++ .../restassured/learner/CourseController.java | 31 +++++++++ .../CourseControllerExceptionHandler.java | 18 ++++++ .../learner/CourseNotFoundException.java | 8 +++ .../restassured/learner/CourseService.java | 27 ++++++++ .../CourseControllerIntegrationTest.java | 40 ++++++++++++ .../learner/CourseControllerUnitTest.java | 63 +++++++++++++++++++ 8 files changed, 226 insertions(+), 10 deletions(-) create mode 100644 testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/Course.java create mode 100644 testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseController.java create mode 100644 testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseControllerExceptionHandler.java create mode 100644 testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseNotFoundException.java create mode 100644 testing-modules/rest-assured/src/main/java/com/baeldung/restassured/learner/CourseService.java create mode 100644 testing-modules/rest-assured/src/test/java/com/baeldung/restassured/learner/CourseControllerIntegrationTest.java create mode 100644 testing-modules/rest-assured/src/test/java/com/baeldung/restassured/learner/CourseControllerUnitTest.java 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()); + } +}