├── .github ├── actions │ └── movies-app-final │ │ └── action.yml └── workflows │ └── gradle.yml ├── .gitignore ├── README.md ├── movie-app-boot ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── learnwiremock │ │ │ ├── MovieAppBootApplication.java │ │ │ ├── config │ │ │ └── MovieAppConfig.java │ │ │ ├── constants │ │ │ └── MoviesAppConstants.java │ │ │ ├── dto │ │ │ └── Movie.java │ │ │ ├── exception │ │ │ └── MovieErrorResponse.java │ │ │ └── service │ │ │ └── MoviesRestClient.java │ └── resources │ │ └── application.properties │ └── test │ ├── java │ └── com │ │ └── learnwiremock │ │ └── service │ │ ├── MoviesRestClientJunit5Test.java │ │ ├── MoviesRestClientJunitRuleTest.java │ │ ├── MoviesRestClientTest.java │ │ └── MoviesRestClientWireMockExtensionTest.java │ └── resources │ └── __files │ ├── 404-invalid-input.json │ ├── 404-movieId.json │ ├── 404-moviename.json │ ├── 404-movieyear.json │ ├── add-movie-template.json │ ├── add-movie.json │ ├── addmovie-invalidinput.json │ ├── all-movies.json │ ├── avengers.json │ ├── movie-byname-template.json │ ├── movie-template.json │ ├── movie.json │ ├── movie1.json │ ├── updatemovie-template.json │ └── year-template.json ├── movies-app-final ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── learnwiremock │ │ ├── constants │ │ └── MoviesAppConstants.java │ │ ├── dto │ │ └── Movie.java │ │ ├── exception │ │ └── MovieErrorResponse.java │ │ └── service │ │ └── MoviesRestClient.java │ └── test │ ├── java │ └── com │ │ └── learnwiremock │ │ └── service │ │ ├── MoviesRestClientServerFaultTest.java │ │ └── MoviesRestClientTest.java │ └── resources │ └── __files │ ├── 400-invalid-input.json │ ├── 404-movieId.json │ ├── 404-movieName.json │ ├── 404-moviename.json │ ├── 404-movieyear.json │ ├── add-movie-template-approach1.json │ ├── add-movie-template.json │ ├── add-movie.json │ ├── all-movies.json │ ├── avengers.json │ ├── movie-byName-template.json │ ├── movie-template.json │ ├── movie.json │ ├── updatemovie-template.json │ └── year-template.json ├── movies-app-junit4 ├── .gitignore ├── README.md ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── learnwiremock │ │ ├── constants │ │ └── MoviesAppConstants.java │ │ ├── dto │ │ └── Movie.java │ │ ├── exception │ │ └── MovieErrorResponse.java │ │ └── service │ │ └── MoviesRestClient.java │ └── test │ ├── java │ └── com │ │ └── learnwiremock │ │ └── service │ │ ├── MoviesRestClientServerFaultTest.java │ │ └── MoviesRestClientTest.java │ └── resources │ └── __files │ ├── 400-invalid-input.json │ ├── 404-movieId.json │ ├── 404-moviename.json │ ├── 404-movieyear.json │ ├── add-movie-template.json │ ├── add-movie.json │ ├── all-movies.json │ ├── avengers.json │ ├── movie-byname-template.json │ ├── movie-template.json │ ├── movie.json │ ├── updatemovie-template.json │ └── year-template.json ├── movies-app ├── .gitignore ├── README.md ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── learnwiremock │ │ ├── constants │ │ └── MovieAppConstants.java │ │ ├── dto │ │ └── Movie.java │ │ ├── exception │ │ └── MovieErrorResponse.java │ │ └── service │ │ └── MoviesRestClient.java │ └── test │ └── java │ └── com │ └── learnwiremock │ ├── .DS_Store │ ├── helper │ └── TestHelper.java │ └── service │ └── MoviesRestClientTest.java └── movies-restful-service ├── README.md ├── movies-restful-service-beyond-java8.jar └── movies-restful-service-java8.jar /.github/actions/movies-app-final/action.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - name: Set up JDK 1.8 11 | uses: actions/setup-java@v1 12 | with: 13 | java-version: 1.8 14 | - name: Build with Gradle 15 | run: ./gradlew build 16 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | on: [push] 3 | jobs: 4 | gradle: 5 | strategy: 6 | matrix: 7 | os: [ubuntu-latest, macos-latest, windows-latest] 8 | runs-on: ${{ matrix.os }} 9 | steps: 10 | - uses: actions/checkout@v1 11 | - uses: actions/setup-java@v1 12 | with: 13 | java-version: 11 14 | - uses: eskatos/gradle-command-action@v1 15 | with: 16 | arguments: build 17 | wrapper-directory: movies-app-final/gradle/wrapper 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | .DS_Store 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wiremock-for-java-developers 2 | This repository has the code to explore for the wiremock course. 3 | - **movie-app-boot** - This codebase has the intergation of Spring Boot and WireMock. 4 | - **movies-app-final** - This codebase has the RestClients built with Spring WebClient and the automated test cases interact with the wiremock using JUnit5. 5 | - **movies-app-junit4** - This codebase has the RestClients built with Spring WebClient and the automated test cases interact with the wiremock using JUnit4. 6 | - **movies-app** - This codebase has the RestClients built with Spring WebClient and the automated test cases interact with the actual **movies-restful-service**. 7 | - **movies-restful-service** - This codebase has the RestClients built with Spring WebClient and the automated test cases interact with the actual **movies-restful-service**. 8 | 9 | 10 | ## Movies RestFul Service 11 | 12 | - Click on the below link for to learn more about the Movies RestFul Service. 13 | 14 | - [Movies RestFul Service](https://github.com/dilipsundarraj1/wiremock-for-java-developers/tree/master/movies-restful-service) 15 | -------------------------------------------------------------------------------- /movie-app-boot/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /movie-app-boot/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.8.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'com.learnwiremock' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | maven { url "https://repository.mulesoft.org/nexus/content/repositories/public/" } 14 | 15 | } 16 | 17 | test{ 18 | useJUnitPlatform() 19 | } 20 | 21 | 22 | dependencies { 23 | implementation 'org.springframework.boot:spring-boot-starter-webflux' 24 | 25 | testImplementation 'io.projectreactor:reactor-test' 26 | 27 | compileOnly 'org.projectlombok:lombok:1.18.8' 28 | annotationProcessor 'org.projectlombok:lombok:1.18.8' 29 | 30 | 31 | testImplementation ('org.springframework.boot:spring-boot-starter-test') 32 | 33 | //junit5 dependencies 34 | testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.5.1' 35 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.1' 36 | testRuntimeOnly 'org.junit.platform:junit-platform-engine:1.5.1' 37 | testRuntimeOnly 'org.junit.platform:junit-platform-commons:1.5.1' 38 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.1' 39 | 40 | 41 | //wiremock-junit5 42 | testImplementation "com.github.JensPiegsa:wiremock-extension:0.4.0" 43 | 44 | //wiremock 45 | testImplementation "org.springframework.cloud:spring-cloud-contract-wiremock:2.1.3.RELEASE" 46 | testImplementation "com.github.tomakehurst:wiremock-jre8-standalone:2.24.1" 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /movie-app-boot/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dilipsundarraj1/wiremock-for-java-developers/3321de471628cb58641f5aa021503dd5ff791872/movie-app-boot/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /movie-app-boot/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Sep 18 14:08:23 CDT 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /movie-app-boot/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /movie-app-boot/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /movie-app-boot/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'movie-app-boot' 2 | -------------------------------------------------------------------------------- /movie-app-boot/src/main/java/com/learnwiremock/MovieAppBootApplication.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class MovieAppBootApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(MovieAppBootApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /movie-app-boot/src/main/java/com/learnwiremock/config/MovieAppConfig.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.config; 2 | 3 | import io.netty.channel.ChannelOption; 4 | import io.netty.handler.timeout.ReadTimeoutHandler; 5 | import io.netty.handler.timeout.WriteTimeoutHandler; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.http.client.reactive.ReactorClientHttpConnector; 10 | import org.springframework.web.reactive.function.client.WebClient; 11 | import reactor.netty.http.client.HttpClient; 12 | import reactor.netty.tcp.TcpClient; 13 | 14 | @Configuration 15 | public class MovieAppConfig { 16 | 17 | @Value("${movieapp.baseUrl}") 18 | private String baseUrl; 19 | 20 | @Bean 21 | public WebClient webClient(){ 22 | 23 | TcpClient tcpClient = TcpClient.create() 24 | .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) 25 | .doOnConnected(connection -> { 26 | connection.addHandlerLast(new ReadTimeoutHandler(5)) 27 | .addHandlerLast(new WriteTimeoutHandler(5)); 28 | }); 29 | 30 | return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient))) 31 | .baseUrl(baseUrl).build(); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /movie-app-boot/src/main/java/com/learnwiremock/constants/MoviesAppConstants.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.constants; 2 | 3 | public class MoviesAppConstants { 4 | 5 | public static final String GET_ALL_MOVIES_V1 = "/movieservice/v1/allMovies"; 6 | public static final String MOVIE_BY_ID_PATH_PARAM_V1 = "/movieservice/v1/movie/{id}"; 7 | public static final String MOVIE_BY_NAME_QUERY_PARAM_V1 = "/movieservice/v1/movieName"; 8 | public static final String MOVIE_BY_YEAR_QUERY_PARAM_V1 ="/movieservice/v1/movieYear"; 9 | public static final String ADD_MOVIE_V1 ="/movieservice/v1/movie"; 10 | public static final String MOVIE_BY_NAME_PATH_PARAM_V1 = "/movieservice/v1/movieName/{name}"; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /movie-app-boot/src/main/java/com/learnwiremock/dto/Movie.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.dto; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.time.LocalDate; 10 | 11 | @Data 12 | @Builder 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class Movie { 16 | 17 | private Long movie_id; 18 | 19 | private String name; 20 | 21 | private Integer year; 22 | 23 | private String cast; 24 | 25 | private LocalDate release_date; 26 | } 27 | -------------------------------------------------------------------------------- /movie-app-boot/src/main/java/com/learnwiremock/exception/MovieErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.exception; 2 | 3 | public class MovieErrorResponse extends RuntimeException { 4 | 5 | public MovieErrorResponse(String message, Throwable cause) { 6 | super(message, cause); 7 | } 8 | public MovieErrorResponse(Throwable cause) { 9 | super(cause); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /movie-app-boot/src/main/java/com/learnwiremock/service/MoviesRestClient.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.learnwiremock.dto.Movie; 4 | import com.learnwiremock.exception.MovieErrorResponse; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.web.reactive.function.client.WebClient; 9 | import org.springframework.web.reactive.function.client.WebClientResponseException; 10 | import org.springframework.web.util.UriComponentsBuilder; 11 | 12 | import java.net.URI; 13 | import java.util.List; 14 | 15 | import static com.learnwiremock.constants.MoviesAppConstants.*; 16 | 17 | 18 | @Slf4j 19 | @Component 20 | public class MoviesRestClient { 21 | 22 | @Autowired 23 | private WebClient webClient; 24 | 25 | 26 | /** 27 | * Retrieve all the movies from the service. 28 | * 29 | * @return 30 | */ 31 | public List retrieveAllMovies() { 32 | List movieList; 33 | try { 34 | log.info("Inside retrieve all movies"); 35 | movieList = webClient.get().uri(GET_ALL_MOVIES_V1) 36 | .retrieve() // actual call is made to the api 37 | .bodyToFlux(Movie.class) //body is converted to flux(Represents multiple items) 38 | .collectList() // collecting the httpResponse as a list\ 39 | .block(); // This call makes the Webclient to behave as a synchronous client. 40 | log.info("after the call"); 41 | } catch (WebClientResponseException ex) { 42 | log.error("WebClientResponseException - Error Message is : {} ", ex, ex.getResponseBodyAsString()); 43 | throw new MovieErrorResponse(ex.getStatusText(), ex); 44 | } catch (Exception ex) { 45 | log.error("Exception - The Error Message is {} and exception is ", ex.getMessage() + ex); 46 | throw new MovieErrorResponse(ex.getMessage(), ex); 47 | } 48 | return movieList; 49 | } 50 | 51 | public Movie retrieveMovieById(Integer movieId) { 52 | Movie movie; 53 | try { 54 | movie = webClient.get().uri(MOVIE_BY_ID_PATH_PARAM_V1, movieId) //mapping the movie id to the url 55 | .retrieve() 56 | .bodyToMono(Movie.class) //body is converted to Mono(Represents single item) 57 | .block(); 58 | } catch (WebClientResponseException ex) { 59 | log.error("WebClientResponseException - Exception is {} and the Error Message is : {}", ex, ex.getResponseBodyAsString()); 60 | throw new MovieErrorResponse(ex.getStatusText(), ex); 61 | } catch (Exception ex) { 62 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 63 | throw new MovieErrorResponse(ex); 64 | } 65 | return movie; 66 | } 67 | 68 | 69 | public List retrieveMovieByName(String movieName) { 70 | 71 | List movieList = null; 72 | String retrieveByNameUri = UriComponentsBuilder.fromUriString( MOVIE_BY_NAME_QUERY_PARAM_V1) 73 | .queryParam("movie_name", movieName) 74 | .buildAndExpand() 75 | .toUriString(); 76 | 77 | try { 78 | movieList = webClient.get().uri(retrieveByNameUri) 79 | .retrieve() 80 | .bodyToFlux(Movie.class) 81 | .collectList() 82 | .block(); 83 | } catch (WebClientResponseException ex) { 84 | log.error("WebClientResponseException - Exception is {} and the Error Message is : {}", ex, ex.getResponseBodyAsString()); 85 | throw new MovieErrorResponse(ex.getStatusText(), ex); 86 | } catch (Exception ex) { 87 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 88 | throw new MovieErrorResponse(ex); 89 | } 90 | return movieList; 91 | } 92 | 93 | 94 | /** 95 | * This method makes a REST call to the Movies RESTFUL Service and retrieves a list of Movies as a response based on the year. 96 | * 97 | * @param year - Integer (Example : 2012,2013 etc.,) 98 | * @return - List 99 | */ 100 | public List retreieveMovieByYear(Integer year) { 101 | String retrieveByYearUri = UriComponentsBuilder.fromUriString( MOVIE_BY_YEAR_QUERY_PARAM_V1) 102 | .queryParam("year", year) 103 | .buildAndExpand() 104 | .toUriString(); 105 | List movieList; 106 | 107 | try { 108 | movieList = webClient.get().uri(retrieveByYearUri) 109 | .retrieve() 110 | .bodyToFlux(Movie.class) 111 | .collectList() 112 | .block(); 113 | } catch (WebClientResponseException ex) { 114 | log.error("WebClientResponseException in retreieveMovieByYear {} and the Error Message is : {} ", ex, ex.getResponseBodyAsString()); 115 | throw new MovieErrorResponse(ex.getStatusText(), ex); 116 | } catch (Exception ex) { 117 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 118 | throw new MovieErrorResponse(ex); 119 | } 120 | return movieList; 121 | } 122 | 123 | /** 124 | * This method makes the REST call to add a new Movie to the Movies RESTFUL Service. 125 | * 126 | * @param newMovie 127 | * @return 128 | */ 129 | public Movie addNewMovie(Movie newMovie) { 130 | Movie movie; 131 | try { 132 | movie = webClient.post().uri( ADD_MOVIE_V1) 133 | .syncBody(newMovie) 134 | .retrieve() 135 | .bodyToMono(Movie.class) 136 | .block(); 137 | log.info("New Movie SuccessFully addded {} ", movie); 138 | } catch (WebClientResponseException ex) { 139 | log.error("WebClientResponseException - Error Message is : {} , and the Error Response Body is {}", ex, ex.getResponseBodyAsString()); 140 | throw new MovieErrorResponse(ex.getStatusText(), ex); 141 | } catch (Exception ex) { 142 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 143 | throw new MovieErrorResponse(ex); 144 | } 145 | return movie; 146 | } 147 | 148 | public Movie updateMovie(Integer movieId, Movie movie) { 149 | Movie updatedMovie; 150 | 151 | try { 152 | updatedMovie = webClient.put().uri( MOVIE_BY_ID_PATH_PARAM_V1, movieId) 153 | .syncBody(movie) 154 | .retrieve() 155 | .bodyToMono(Movie.class) 156 | .block(); 157 | log.info(" Movie SuccessFully updated {} ", updatedMovie); 158 | } catch (WebClientResponseException ex) { 159 | log.error("WebClientResponseException - Error Message is : {}", ex, ex.getResponseBodyAsString()); 160 | throw new MovieErrorResponse(ex.getStatusText(), ex); 161 | } catch (Exception ex) { 162 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 163 | throw new MovieErrorResponse(ex); 164 | } 165 | 166 | return updatedMovie; 167 | } 168 | 169 | public String deleteMovieById(Integer movieId) { 170 | 171 | String response; 172 | try { 173 | response = webClient.delete().uri( MOVIE_BY_ID_PATH_PARAM_V1, movieId) 174 | .retrieve() 175 | .bodyToMono(String.class) 176 | .block(); 177 | }catch (WebClientResponseException ex) { 178 | log.error("WebClientResponseException - Error Message is : {}", ex, ex.getResponseBodyAsString()); 179 | throw new MovieErrorResponse(ex.getStatusText(), ex); 180 | } catch (Exception ex) { 181 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 182 | throw new MovieErrorResponse(ex); 183 | } 184 | 185 | return response; 186 | 187 | } 188 | 189 | public String deleteMovieByName(String movieName) { 190 | 191 | 192 | try { 193 | webClient.delete().uri( MOVIE_BY_NAME_PATH_PARAM_V1, movieName) 194 | .retrieve() 195 | .bodyToMono(Void.class) 196 | .block(); 197 | }catch (WebClientResponseException ex) { 198 | log.error("WebClientResponseException - The Status code is {} and the Error Message is : {}", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 199 | throw new MovieErrorResponse(ex.getStatusText(), ex); 200 | } catch (Exception ex) { 201 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 202 | throw new MovieErrorResponse(ex); 203 | } 204 | return "Movie Deleted SuccessFully"; 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /movie-app-boot/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /movie-app-boot/src/test/java/com/learnwiremock/service/MoviesRestClientJunitRuleTest.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.github.tomakehurst.wiremock.client.WireMock; 5 | import com.github.tomakehurst.wiremock.common.ConsoleNotifier; 6 | import com.github.tomakehurst.wiremock.core.Options; 7 | import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; 8 | import com.github.tomakehurst.wiremock.junit.WireMockRule; 9 | import com.learnwiremock.dto.Movie; 10 | import com.learnwiremock.exception.MovieErrorResponse; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | import org.junit.runner.RunWith; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.boot.test.context.SpringBootTest; 16 | import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; 17 | import org.springframework.http.HttpHeaders; 18 | import org.springframework.http.HttpStatus; 19 | import org.springframework.http.MediaType; 20 | import org.springframework.test.context.TestPropertySource; 21 | import org.springframework.test.context.junit4.SpringRunner; 22 | 23 | 24 | import java.time.LocalDate; 25 | import java.util.List; 26 | 27 | import static com.github.tomakehurst.wiremock.client.WireMock.*; 28 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; 29 | import static com.learnwiremock.constants.MoviesAppConstants.*; 30 | import static org.junit.Assert.assertEquals; 31 | import static org.junit.Assert.assertTrue; 32 | 33 | @RunWith(SpringRunner.class) 34 | @SpringBootTest 35 | @TestPropertySource(properties= {"movieapp.baseUrl=http://localhost:8089"}) 36 | public class MoviesRestClientJunitRuleTest { 37 | 38 | @Autowired 39 | MoviesRestClient moviesRestClient; 40 | 41 | Options options = wireMockConfig(). 42 | port(8089) 43 | .notifier(new ConsoleNotifier(true)) 44 | .extensions(new ResponseTemplateTransformer(true)); 45 | 46 | @Rule 47 | public WireMockRule wireMockRule = new WireMockRule(options); 48 | 49 | 50 | @Test 51 | public void getAllMovies() { 52 | 53 | //given 54 | stubFor(get(WireMock.anyUrl()) 55 | .willReturn(WireMock.aResponse() 56 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 57 | .withStatus(HttpStatus.OK.value()) 58 | .withBodyFile("all-movies.json"))); 59 | //whenx 60 | List movieList = moviesRestClient.retrieveAllMovies(); 61 | System.out.println("movieList : " + movieList); 62 | 63 | //then 64 | assertTrue(!movieList.isEmpty()); 65 | } 66 | 67 | @Test 68 | public void getAllMovies_matchUrlPath() { 69 | 70 | //given 71 | stubFor(get(urlPathEqualTo(GET_ALL_MOVIES_V1)) 72 | .willReturn(WireMock.aResponse() 73 | .withStatus(HttpStatus.OK.value()) 74 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 75 | .withBodyFile("all-movies.json"))); 76 | 77 | //when 78 | List movieList = moviesRestClient.retrieveAllMovies(); 79 | System.out.println("movieList : " + movieList); 80 | 81 | //then 82 | assertTrue(!movieList.isEmpty()); 83 | } 84 | 85 | 86 | @Test 87 | public void retrieveMovieById() { 88 | 89 | //given 90 | //stubFor(get(urlPathEqualTo("/movieservice/v1/movie/1")) 91 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]")) 92 | .willReturn(WireMock.aResponse() 93 | .withStatus(HttpStatus.OK.value()) 94 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 95 | .withBodyFile("movie.json"))); 96 | 97 | //given 98 | Integer movieId = 1; 99 | 100 | //when 101 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 102 | 103 | //then 104 | assertEquals("Batman Begins", movie.getName()); 105 | } 106 | 107 | @Test 108 | public void retrieveMovieById_withResponseTemplating() { 109 | 110 | //given 111 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 112 | .willReturn(WireMock.aResponse() 113 | .withStatus(HttpStatus.OK.value()) 114 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 115 | .withBodyFile("movie-template.json"))); 116 | 117 | 118 | //given 119 | Integer movieId = 200; 120 | 121 | //when 122 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 123 | //then 124 | assertEquals("Batman Begins", movie.getName()); 125 | assertEquals(movieId.intValue(), movie.getMovie_id().intValue()); 126 | } 127 | 128 | 129 | @Test 130 | public void retrieveMovieById_WithPriority() { 131 | 132 | //given 133 | stubFor(get(urlPathMatching("/movieservice/v1/movie/1")) 134 | .atPriority(1) 135 | .willReturn(WireMock.aResponse() 136 | .withStatus(HttpStatus.OK.value()) 137 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 138 | .withBodyFile("movie.json"))); 139 | stubFor(get(urlMatching("/movieservice/v1/movie/([0-9])")) 140 | .willReturn(WireMock.aResponse() 141 | .withStatus(HttpStatus.OK.value()) 142 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 143 | .withBodyFile("movie1.json"))); 144 | 145 | 146 | //given 147 | Integer movieId = 1; 148 | Integer movieId1 = 2; 149 | 150 | //when 151 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 152 | Movie movie1 = moviesRestClient.retrieveMovieById(movieId1); 153 | 154 | //then 155 | assertEquals("Batman Begins", movie.getName()); 156 | assertEquals("Batman Begins1", movie1.getName()); 157 | } 158 | 159 | @Test(expected = MovieErrorResponse.class) 160 | public void retrieveMovieById_NotFound() { 161 | //given 162 | Integer movieId = 100; 163 | stubFor(get(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 164 | .willReturn(WireMock.aResponse() 165 | .withStatus(HttpStatus.NOT_FOUND.value()) 166 | .withBodyFile("404-movieId.json"))); 167 | 168 | //when 169 | moviesRestClient.retrieveMovieById(movieId); 170 | 171 | } 172 | 173 | @Test 174 | public void retrieveMovieByName_UrlEqualTo() { 175 | //dont use urlPathEqualTo when there is queryParem involved. 176 | 177 | //given 178 | String movieName = "Avengers"; 179 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1 + "?movie_name=" + movieName)) 180 | .willReturn(WireMock.aResponse() 181 | .withStatus(HttpStatus.OK.value()) 182 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 183 | .withBodyFile("avengers.json"))); 184 | 185 | //when 186 | List movieList = moviesRestClient.retrieveMovieByName(movieName); 187 | 188 | //then 189 | String expectedCastName = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 190 | assertEquals(4, movieList.size()); 191 | assertEquals(expectedCastName, movieList.get(0).getCast()); 192 | } 193 | 194 | @Test 195 | public void retrieveMovieByName_UrlPathEqualTo_approach2() { 196 | //dont use urlPathEqualTo when there is queryParem involved. 197 | 198 | //given 199 | String movieName = "Avengers"; 200 | stubFor(get(urlPathEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1)) 201 | .withQueryParam("movie_name", equalTo(movieName)) 202 | .willReturn(WireMock.aResponse() 203 | .withStatus(HttpStatus.OK.value()) 204 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 205 | .withBodyFile("avengers.json"))); 206 | 207 | //when 208 | List movieList = moviesRestClient.retrieveMovieByName(movieName); 209 | 210 | //then 211 | String expectedCastName = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 212 | assertEquals(4, movieList.size()); 213 | assertEquals(expectedCastName, movieList.get(0).getCast()); 214 | } 215 | 216 | 217 | @Test(expected = MovieErrorResponse.class) 218 | public void retrieveMovieByName_Not_Found() { 219 | //given 220 | String movieName = "ABC"; 221 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1 + "?movie_name=" + movieName)) 222 | .willReturn(WireMock.aResponse() 223 | .withStatus(HttpStatus.NOT_FOUND.value()) 224 | .withBodyFile("404-moviename.json"))); 225 | 226 | //when 227 | moviesRestClient.retrieveMovieByName(movieName); 228 | } 229 | 230 | @Test 231 | public void retrieveMovieByName_withResponseTemplating() { 232 | //dont use urlPathEqualTo when there is queryParem involved. 233 | 234 | //given 235 | String movieName = "Avengers"; 236 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1 + "?movie_name=" + movieName)) 237 | .willReturn(WireMock.aResponse() 238 | .withStatus(HttpStatus.OK.value()) 239 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 240 | .withBodyFile("movie-byname-template.json"))); 241 | 242 | //when 243 | List movieList = moviesRestClient.retrieveMovieByName(movieName); 244 | System.out.println("movieList : " + movieList); 245 | //then 246 | String expectedCastName = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 247 | assertEquals(4, movieList.size()); 248 | assertEquals(expectedCastName, movieList.get(0).getCast()); 249 | } 250 | 251 | 252 | @Test 253 | public void retrieveMovieByName_urlPathEqualTo() { 254 | //given 255 | String movieName = "Avengers"; 256 | stubFor(get(urlPathEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1)) 257 | // .withQueryParam("movie_name", equalTo(movieName)) 258 | .willReturn(WireMock.aResponse() 259 | .withStatus(HttpStatus.OK.value()) 260 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 261 | .withBodyFile("avengers.json"))); 262 | 263 | //when 264 | List movieList = moviesRestClient.retrieveMovieByName(movieName); 265 | 266 | //then 267 | String expectedCastName = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 268 | assertEquals(4, movieList.size()); 269 | assertEquals(expectedCastName, movieList.get(0).getCast()); 270 | } 271 | 272 | 273 | @Test 274 | public void retrieveMovieByYear() { 275 | //given 276 | Integer year = 2012; 277 | stubFor(get(urlEqualTo(MOVIE_BY_YEAR_QUERY_PARAM_V1 + "?year=" + year)) 278 | .willReturn(WireMock.aResponse() 279 | .withStatus(HttpStatus.OK.value()) 280 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 281 | .withBodyFile("year-template.json"))); 282 | 283 | //when 284 | List movieList = moviesRestClient.retreieveMovieByYear(year); 285 | 286 | //then 287 | assertEquals(2, movieList.size()); 288 | 289 | } 290 | 291 | @Test(expected = MovieErrorResponse.class) 292 | public void retrieveMovieByYear_Not_Found() { 293 | //given 294 | Integer year = 1950; 295 | stubFor(get(urlEqualTo(MOVIE_BY_YEAR_QUERY_PARAM_V1 + "?year=" + year)) 296 | .withQueryParam("year", equalTo(year.toString())) 297 | .willReturn(WireMock.aResponse() 298 | .withStatus(HttpStatus.NOT_FOUND.value()) 299 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 300 | .withBodyFile("404-movieyear.json"))); 301 | 302 | 303 | //when 304 | moviesRestClient.retreieveMovieByYear(year); 305 | 306 | } 307 | 308 | @Test 309 | public void addNewMovie() { 310 | //given 311 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 312 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 313 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 314 | //.withRequestBody(matchingJsonPath("$..name", containing("Toy Story 4"))) 315 | .withRequestBody(matchingJsonPath(("$.name"))) 316 | .withRequestBody(matchingJsonPath(("$.cast"))) 317 | .willReturn(WireMock.aResponse() 318 | .withStatus(HttpStatus.CREATED.value()) 319 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 320 | .withBodyFile("add-movie.json"))); 321 | 322 | 323 | //when 324 | Movie movie = moviesRestClient.addNewMovie(toyStory); 325 | 326 | //then 327 | assertTrue(movie.getMovie_id() != null); 328 | 329 | } 330 | 331 | 332 | @Test 333 | public void addNewMovie_matchingJsonAttributeValue() throws JsonProcessingException { 334 | //given 335 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 336 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 337 | 338 | 339 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 340 | .withRequestBody(matchingJsonPath(("$.name"), equalTo("Toy Story 4"))) 341 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 342 | .willReturn(WireMock.aResponse() 343 | .withStatus(HttpStatus.CREATED.value()) 344 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 345 | .withBodyFile("add-movie.json"))); 346 | 347 | 348 | //when 349 | Movie movie = moviesRestClient.addNewMovie(toyStory); 350 | 351 | //then 352 | assertTrue(movie.getMovie_id() != null); 353 | 354 | } 355 | 356 | @Test 357 | public void addNewMovie_dynamicResponse() { 358 | //given 359 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 360 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 361 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 362 | //.withRequestBody(matchingJsonPath("$..name", containing("Toy Story 4"))) 363 | .withRequestBody(matchingJsonPath(("$.name"))) 364 | .withRequestBody(matchingJsonPath(("$.cast"))) 365 | .willReturn(WireMock.aResponse() 366 | .withStatus(HttpStatus.CREATED.value()) 367 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 368 | .withBodyFile("add-movie-template.json"))); 369 | 370 | 371 | //when 372 | Movie movie = moviesRestClient.addNewMovie(toyStory); 373 | System.out.println("movie : " + movie); 374 | 375 | //then 376 | assertTrue(movie.getMovie_id() != null); 377 | 378 | } 379 | 380 | @Test(expected = MovieErrorResponse.class) 381 | public void addNewMovie_InvlaidInput() { 382 | //given 383 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 384 | Movie toyStory = new Movie(null, null, null, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 385 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 386 | .willReturn(WireMock.aResponse() 387 | .withBodyFile("addmovie-invalidinput.json") 388 | .withStatus(HttpStatus.BAD_REQUEST.value()) 389 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 390 | .withBodyFile("404.json"))); 391 | 392 | //when 393 | moviesRestClient.addNewMovie(toyStory); 394 | 395 | } 396 | 397 | @Test 398 | public void updateMovie() { 399 | //given 400 | String darkNightRisesCrew = "Tom Hardy"; 401 | Movie darkNightRises = new Movie(null, null, null, darkNightRisesCrew, null); 402 | Integer movieId = 3; 403 | stubFor(put(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 404 | .withRequestBody(matchingJsonPath("$.cast", equalTo(darkNightRisesCrew))) 405 | .willReturn(WireMock.aResponse() 406 | .withStatus(HttpStatus.OK.value()) 407 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 408 | .withBodyFile("updatemovie-template.json"))); 409 | 410 | 411 | //when 412 | Movie updatedMovie = moviesRestClient.updateMovie(movieId, darkNightRises); 413 | 414 | //then 415 | String updatedCastName = "Christian Bale, Heath Ledger , Michael Caine, Tom Hardy"; 416 | assertTrue(updatedMovie.getCast().contains(darkNightRisesCrew)); 417 | 418 | 419 | } 420 | 421 | @Test(expected = MovieErrorResponse.class) 422 | public void updateMovie_Not_Found() { 423 | //given 424 | String darkNightRisesCrew = "Tom Hardy"; 425 | Movie darkNightRises = new Movie(null, null, null, darkNightRisesCrew, null); 426 | Integer movieId = 100; 427 | stubFor(put(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 428 | .withRequestBody(matchingJsonPath("$.cast", equalTo(darkNightRisesCrew))) 429 | .willReturn(WireMock.aResponse() 430 | .withStatus(HttpStatus.NOT_FOUND.value()) 431 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 432 | 433 | //when 434 | moviesRestClient.updateMovie(movieId, darkNightRises); 435 | } 436 | 437 | @Test 438 | public void deleteMovie() { 439 | 440 | //given 441 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 442 | .withRequestBody(matchingJsonPath("$.name", equalTo("Toy Story 4"))) 443 | .willReturn(WireMock.aResponse() 444 | .withStatus(HttpStatus.CREATED.value()) 445 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 446 | .withBodyFile("add-movie.json"))); 447 | 448 | stubFor(delete(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 449 | .willReturn(WireMock.aResponse() 450 | .withStatus(HttpStatus.OK.value()) 451 | .withBody("Movie Deleted Successfully"))); 452 | 453 | String toyStoryCrew = "Tom Hanks, Tim Allen"; 454 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, toyStoryCrew, LocalDate.of(2019, 06, 20)); 455 | Movie movie = moviesRestClient.addNewMovie(toyStory); 456 | Integer movieId = movie.getMovie_id().intValue(); 457 | 458 | //when 459 | String response = moviesRestClient.deleteMovieById(movieId); 460 | 461 | //then 462 | String expectedResponse = "Movie Deleted Successfully"; 463 | assertEquals(expectedResponse, response); 464 | 465 | } 466 | 467 | @Test(expected = MovieErrorResponse.class) 468 | public void deleteMovie_notFound() { 469 | 470 | //given 471 | stubFor(delete(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 472 | .willReturn(WireMock.aResponse() 473 | .withStatus(HttpStatus.NOT_FOUND.value()))); 474 | 475 | Integer movieId = 100; 476 | 477 | //when 478 | moviesRestClient.deleteMovieById(movieId); 479 | 480 | } 481 | 482 | @Test 483 | public void deleteMovieByName() { 484 | 485 | //given 486 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 487 | .withRequestBody(matchingJsonPath("$.name", equalTo("Toy Story 5"))) 488 | .willReturn(WireMock.aResponse() 489 | .withStatus(HttpStatus.CREATED.value()) 490 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 491 | .withBodyFile("add-movie.json"))); 492 | 493 | stubFor(delete(urlPathMatching("/movieservice/v1/movieName/.*")) 494 | .willReturn(WireMock.ok())); 495 | 496 | String toyStoryCrew = "Tom Hanks, Tim Allen"; 497 | Movie toyStory = new Movie(null, "Toy Story 5", 2019, toyStoryCrew, LocalDate.of(2019, 06, 20)); 498 | Movie movie = moviesRestClient.addNewMovie(toyStory); 499 | 500 | //when 501 | String responseMessage = moviesRestClient.deleteMovieByName(movie.getName()); 502 | 503 | //then 504 | assertEquals("Movie Deleted SuccessFully", responseMessage); 505 | 506 | verify(postRequestedFor(urlPathEqualTo(ADD_MOVIE_V1)) 507 | .withRequestBody(matchingJsonPath("$.name", equalTo("Toy Story 5")))); 508 | verify(deleteRequestedFor((urlPathMatching("/movieservice/v1/movieName/.*")))); 509 | verify(exactly(1), postRequestedFor(urlPathEqualTo(ADD_MOVIE_V1)) 510 | .withRequestBody(matchingJsonPath("$.name", equalTo("Toy Story 5")))); 511 | verify(exactly(1), deleteRequestedFor((urlPathMatching("/movieservice/v1/movieName/.*")))); 512 | 513 | 514 | } 515 | 516 | @Test(expected = MovieErrorResponse.class) 517 | public void deleteMovieByName_NotFound() { 518 | 519 | //given 520 | String movieName = "ABC"; 521 | stubFor(delete(urlPathMatching("/movieservice/v1/movieName/.*")) 522 | .willReturn(WireMock.serverError())); 523 | 524 | 525 | //then 526 | moviesRestClient.deleteMovieByName(movieName); 527 | 528 | } 529 | } 530 | -------------------------------------------------------------------------------- /movie-app-boot/src/test/java/com/learnwiremock/service/MoviesRestClientTest.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.github.tomakehurst.wiremock.WireMockServer; 5 | import com.github.tomakehurst.wiremock.client.WireMock; 6 | import com.github.tomakehurst.wiremock.common.ConsoleNotifier; 7 | import com.github.tomakehurst.wiremock.core.Options; 8 | import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; 9 | import com.learnwiremock.dto.Movie; 10 | import com.learnwiremock.exception.MovieErrorResponse; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | import org.junit.runner.RunWith; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.boot.context.properties.ConfigurationProperties; 16 | import org.springframework.boot.test.context.SpringBootTest; 17 | import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; 18 | import org.springframework.http.HttpHeaders; 19 | import org.springframework.http.HttpStatus; 20 | import org.springframework.http.MediaType; 21 | import org.springframework.test.context.TestPropertySource; 22 | import org.springframework.test.context.junit4.SpringRunner; 23 | import org.springframework.web.reactive.function.client.WebClient; 24 | 25 | import java.time.LocalDate; 26 | import java.util.List; 27 | 28 | import static com.github.tomakehurst.wiremock.client.WireMock.*; 29 | import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; 30 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; 31 | import static com.learnwiremock.constants.MoviesAppConstants.*; 32 | import static org.junit.Assert.assertEquals; 33 | import static org.junit.Assert.assertTrue; 34 | import com.learnwiremock.constants.MoviesAppConstants.*; 35 | 36 | @RunWith(SpringRunner.class) 37 | @SpringBootTest 38 | @AutoConfigureWireMock(port = 8088) 39 | @TestPropertySource(properties= {"movieapp.baseUrl=http://localhost:8088"}) 40 | public class MoviesRestClientTest { 41 | 42 | 43 | @Autowired 44 | MoviesRestClient moviesRestClient; 45 | 46 | @Test 47 | public void getAllMovies() { 48 | 49 | //given 50 | stubFor(get(WireMock.anyUrl()) 51 | .willReturn(WireMock.aResponse() 52 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 53 | .withStatus(HttpStatus.OK.value()) 54 | .withBodyFile("all-movies.json"))); 55 | //whenx 56 | List movieList = moviesRestClient.retrieveAllMovies(); 57 | System.out.println("movieList : " + movieList); 58 | 59 | //then 60 | assertTrue(!movieList.isEmpty()); 61 | } 62 | 63 | @Test 64 | public void getAllMovies_matchUrlPath() { 65 | 66 | //given 67 | stubFor(get(urlPathEqualTo(GET_ALL_MOVIES_V1)) 68 | .willReturn(WireMock.aResponse() 69 | .withStatus(HttpStatus.OK.value()) 70 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 71 | .withBodyFile("all-movies.json"))); 72 | 73 | //when 74 | List movieList = moviesRestClient.retrieveAllMovies(); 75 | System.out.println("movieList : " + movieList); 76 | 77 | //then 78 | assertTrue(!movieList.isEmpty()); 79 | } 80 | 81 | 82 | @Test 83 | public void retrieveMovieById() { 84 | 85 | //given 86 | //stubFor(get(urlPathEqualTo("/movieservice/v1/movie/1")) 87 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]")) 88 | .willReturn(WireMock.aResponse() 89 | .withStatus(HttpStatus.OK.value()) 90 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 91 | .withBodyFile("movie.json"))); 92 | 93 | //given 94 | Integer movieId = 1; 95 | 96 | //when 97 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 98 | 99 | //then 100 | assertEquals("Batman Begins", movie.getName()); 101 | } 102 | 103 | // @Test 104 | public void retrieveMovieById_withResponseTemplating() { 105 | 106 | //given 107 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 108 | .willReturn(WireMock.aResponse() 109 | .withStatus(HttpStatus.OK.value()) 110 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 111 | .withBodyFile("movie-template.json"))); 112 | 113 | 114 | //given 115 | Integer movieId = 200; 116 | 117 | //when 118 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 119 | //then 120 | assertEquals("Batman Begins", movie.getName()); 121 | assertEquals(movieId.intValue(), movie.getMovie_id().intValue()); 122 | } 123 | 124 | 125 | @Test 126 | public void retrieveMovieById_WithPriority() { 127 | 128 | //given 129 | stubFor(get(urlPathMatching("/movieservice/v1/movie/1")) 130 | .atPriority(1) 131 | .willReturn(WireMock.aResponse() 132 | .withStatus(HttpStatus.OK.value()) 133 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 134 | .withBodyFile("movie.json"))); 135 | stubFor(get(urlMatching("/movieservice/v1/movie/([0-9])")) 136 | .willReturn(WireMock.aResponse() 137 | .withStatus(HttpStatus.OK.value()) 138 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 139 | .withBodyFile("movie1.json"))); 140 | 141 | 142 | //given 143 | Integer movieId = 1; 144 | Integer movieId1 = 2; 145 | 146 | //when 147 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 148 | Movie movie1 = moviesRestClient.retrieveMovieById(movieId1); 149 | 150 | //then 151 | assertEquals("Batman Begins", movie.getName()); 152 | assertEquals("Batman Begins1", movie1.getName()); 153 | } 154 | 155 | @Test(expected = MovieErrorResponse.class) 156 | public void retrieveMovieById_NotFound() { 157 | //given 158 | Integer movieId = 100; 159 | stubFor(get(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 160 | .willReturn(WireMock.aResponse() 161 | .withStatus(HttpStatus.NOT_FOUND.value()) 162 | .withBodyFile("404-movieId.json"))); 163 | 164 | //when 165 | moviesRestClient.retrieveMovieById(movieId); 166 | 167 | } 168 | 169 | @Test 170 | public void retrieveMovieByName_UrlEqualTo() { 171 | //dont use urlPathEqualTo when there is queryParem involved. 172 | 173 | //given 174 | String movieName = "Avengers"; 175 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1 + "?movie_name=" + movieName)) 176 | .willReturn(WireMock.aResponse() 177 | .withStatus(HttpStatus.OK.value()) 178 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 179 | .withBodyFile("avengers.json"))); 180 | 181 | //when 182 | List movieList = moviesRestClient.retrieveMovieByName(movieName); 183 | 184 | //then 185 | String expectedCastName = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 186 | assertEquals(4, movieList.size()); 187 | assertEquals(expectedCastName, movieList.get(0).getCast()); 188 | } 189 | 190 | @Test 191 | public void retrieveMovieByName_UrlPathEqualTo_approach2() { 192 | //dont use urlPathEqualTo when there is queryParem involved. 193 | 194 | //given 195 | String movieName = "Avengers"; 196 | stubFor(get(urlPathEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1)) 197 | .withQueryParam("movie_name", equalTo(movieName)) 198 | .willReturn(WireMock.aResponse() 199 | .withStatus(HttpStatus.OK.value()) 200 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 201 | .withBodyFile("avengers.json"))); 202 | 203 | //when 204 | List movieList = moviesRestClient.retrieveMovieByName(movieName); 205 | 206 | //then 207 | String expectedCastName = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 208 | assertEquals(4, movieList.size()); 209 | assertEquals(expectedCastName, movieList.get(0).getCast()); 210 | } 211 | 212 | 213 | @Test(expected = MovieErrorResponse.class) 214 | public void retrieveMovieByName_Not_Found() { 215 | //given 216 | String movieName = "ABC"; 217 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1 + "?movie_name=" + movieName)) 218 | .willReturn(WireMock.aResponse() 219 | .withStatus(HttpStatus.NOT_FOUND.value()) 220 | .withBodyFile("404-moviename.json"))); 221 | 222 | //when 223 | moviesRestClient.retrieveMovieByName(movieName); 224 | 225 | } 226 | 227 | @Test 228 | public void retrieveMovieByName_withResponseTemplating() { 229 | //dont use urlPathEqualTo when there is queryParem involved. 230 | 231 | //given 232 | String movieName = "Avengers"; 233 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1 + "?movie_name=" + movieName)) 234 | .willReturn(WireMock.aResponse() 235 | .withStatus(HttpStatus.OK.value()) 236 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 237 | .withBodyFile("movie-byname-template.json"))); 238 | 239 | //when 240 | List movieList = moviesRestClient.retrieveMovieByName(movieName); 241 | System.out.println("movieList : " + movieList); 242 | //then 243 | String expectedCastName = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 244 | assertEquals(4, movieList.size()); 245 | assertEquals(expectedCastName, movieList.get(0).getCast()); 246 | } 247 | 248 | 249 | @Test 250 | public void retrieveMovieByName_urlPathEqualTo() { 251 | //given 252 | String movieName = "Avengers"; 253 | stubFor(get(urlPathEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1)) 254 | // .withQueryParam("movie_name", equalTo(movieName)) 255 | .willReturn(WireMock.aResponse() 256 | .withStatus(HttpStatus.OK.value()) 257 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 258 | .withBodyFile("avengers.json"))); 259 | 260 | //when 261 | List movieList = moviesRestClient.retrieveMovieByName(movieName); 262 | 263 | //then 264 | String expectedCastName = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 265 | assertEquals(4, movieList.size()); 266 | assertEquals(expectedCastName, movieList.get(0).getCast()); 267 | } 268 | 269 | 270 | //@Test 271 | public void retrieveMovieByYear() { 272 | //given 273 | Integer year = 2012; 274 | stubFor(get(urlEqualTo(MOVIE_BY_YEAR_QUERY_PARAM_V1 + "?year=" + year)) 275 | .willReturn(WireMock.aResponse() 276 | .withStatus(HttpStatus.OK.value()) 277 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 278 | .withBodyFile("year-template.json"))); 279 | 280 | //when 281 | List movieList = moviesRestClient.retreieveMovieByYear(year); 282 | 283 | //then 284 | assertEquals(2, movieList.size()); 285 | 286 | } 287 | 288 | @Test(expected = MovieErrorResponse.class) 289 | public void retrieveMovieByYear_Not_Found() { 290 | //given 291 | Integer year = 1950; 292 | stubFor(get(urlEqualTo(MOVIE_BY_YEAR_QUERY_PARAM_V1 + "?year=" + year)) 293 | .withQueryParam("year", equalTo(year.toString())) 294 | .willReturn(WireMock.aResponse() 295 | .withStatus(HttpStatus.NOT_FOUND.value()) 296 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 297 | .withBodyFile("404-movieyear.json"))); 298 | 299 | 300 | //when 301 | moviesRestClient.retreieveMovieByYear(year); 302 | 303 | } 304 | 305 | @Test 306 | public void addNewMovie() { 307 | //given 308 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 309 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 310 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 311 | //.withRequestBody(matchingJsonPath("$..name", containing("Toy Story 4"))) 312 | .withRequestBody(matchingJsonPath(("$.name"))) 313 | .withRequestBody(matchingJsonPath(("$.cast"))) 314 | .willReturn(WireMock.aResponse() 315 | .withStatus(HttpStatus.CREATED.value()) 316 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 317 | .withBodyFile("add-movie.json"))); 318 | 319 | 320 | //when 321 | Movie movie = moviesRestClient.addNewMovie(toyStory); 322 | 323 | //then 324 | assertTrue(movie.getMovie_id() != null); 325 | 326 | } 327 | 328 | 329 | @Test 330 | public void addNewMovie_matchingJsonAttributeValue() throws JsonProcessingException { 331 | //given 332 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 333 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 334 | 335 | 336 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 337 | .withRequestBody(matchingJsonPath(("$.name"), equalTo("Toy Story 4"))) 338 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 339 | .willReturn(WireMock.aResponse() 340 | .withStatus(HttpStatus.CREATED.value()) 341 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 342 | .withBodyFile("add-movie.json"))); 343 | 344 | 345 | //when 346 | Movie movie = moviesRestClient.addNewMovie(toyStory); 347 | 348 | //then 349 | assertTrue(movie.getMovie_id() != null); 350 | 351 | } 352 | 353 | // @Test 354 | public void addNewMovie_dynamicResponse() { 355 | //given 356 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 357 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 358 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 359 | //.withRequestBody(matchingJsonPath("$..name", containing("Toy Story 4"))) 360 | .withRequestBody(matchingJsonPath(("$.name"))) 361 | .withRequestBody(matchingJsonPath(("$.cast"))) 362 | .willReturn(WireMock.aResponse() 363 | .withStatus(HttpStatus.CREATED.value()) 364 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 365 | .withBodyFile("add-movie-template.json"))); 366 | 367 | 368 | //when 369 | Movie movie = moviesRestClient.addNewMovie(toyStory); 370 | System.out.println("movie : " + movie); 371 | 372 | //then 373 | assertTrue(movie.getMovie_id() != null); 374 | 375 | } 376 | 377 | @Test(expected = MovieErrorResponse.class) 378 | public void addNewMovie_InvlaidInput() { 379 | //given 380 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 381 | Movie toyStory = new Movie(null, null, null, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 382 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 383 | .willReturn(WireMock.aResponse() 384 | .withBodyFile("addmovie-invalidinput.json") 385 | .withStatus(HttpStatus.BAD_REQUEST.value()) 386 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 387 | .withBodyFile("404.json"))); 388 | 389 | //when 390 | moviesRestClient.addNewMovie(toyStory); 391 | 392 | } 393 | 394 | //@Test 395 | public void updateMovie() { 396 | //given 397 | String darkNightRisesCrew = "Tom Hardy"; 398 | Movie darkNightRises = new Movie(null, null, null, darkNightRisesCrew, null); 399 | Integer movieId = 3; 400 | stubFor(put(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 401 | .withRequestBody(matchingJsonPath("$.cast", equalTo(darkNightRisesCrew))) 402 | .willReturn(WireMock.aResponse() 403 | .withStatus(HttpStatus.OK.value()) 404 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 405 | .withBodyFile("updatemovie-template.json"))); 406 | 407 | 408 | //when 409 | Movie updatedMovie = moviesRestClient.updateMovie(movieId, darkNightRises); 410 | 411 | //then 412 | String updatedCastName = "Christian Bale, Heath Ledger , Michael Caine, Tom Hardy"; 413 | assertTrue(updatedMovie.getCast().contains(darkNightRisesCrew)); 414 | 415 | 416 | } 417 | 418 | @Test(expected = MovieErrorResponse.class) 419 | public void updateMovie_Not_Found() { 420 | //given 421 | String darkNightRisesCrew = "Tom Hardy"; 422 | Movie darkNightRises = new Movie(null, null, null, darkNightRisesCrew, null); 423 | Integer movieId = 100; 424 | stubFor(put(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 425 | .withRequestBody(matchingJsonPath("$.cast", equalTo(darkNightRisesCrew))) 426 | .willReturn(WireMock.aResponse() 427 | .withStatus(HttpStatus.NOT_FOUND.value()) 428 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 429 | 430 | //when 431 | moviesRestClient.updateMovie(movieId, darkNightRises); 432 | } 433 | 434 | @Test 435 | public void deleteMovie() { 436 | 437 | //given 438 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 439 | .withRequestBody(matchingJsonPath("$.name", equalTo("Toy Story 4"))) 440 | .willReturn(WireMock.aResponse() 441 | .withStatus(HttpStatus.CREATED.value()) 442 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 443 | .withBodyFile("add-movie.json"))); 444 | 445 | stubFor(delete(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 446 | .willReturn(WireMock.aResponse() 447 | .withStatus(HttpStatus.OK.value()) 448 | .withBody("Movie Deleted Successfully"))); 449 | 450 | String toyStoryCrew = "Tom Hanks, Tim Allen"; 451 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, toyStoryCrew, LocalDate.of(2019, 06, 20)); 452 | Movie movie = moviesRestClient.addNewMovie(toyStory); 453 | Integer movieId = movie.getMovie_id().intValue(); 454 | 455 | //when 456 | String response = moviesRestClient.deleteMovieById(movieId); 457 | 458 | //then 459 | String expectedResponse = "Movie Deleted Successfully"; 460 | assertEquals(expectedResponse, response); 461 | 462 | } 463 | 464 | @Test(expected = MovieErrorResponse.class) 465 | public void deleteMovie_notFound() { 466 | 467 | //given 468 | stubFor(delete(urlPathMatching("/movieservice/v1/movie/([0-9]+)")) 469 | .willReturn(WireMock.aResponse() 470 | .withStatus(HttpStatus.NOT_FOUND.value()))); 471 | 472 | Integer movieId = 100; 473 | 474 | //when 475 | moviesRestClient.deleteMovieById(movieId); 476 | 477 | } 478 | 479 | @Test 480 | public void deleteMovieByName() { 481 | 482 | //given 483 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 484 | .withRequestBody(matchingJsonPath("$.name", equalTo("Toy Story 5"))) 485 | .willReturn(WireMock.aResponse() 486 | .withStatus(HttpStatus.CREATED.value()) 487 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 488 | .withBodyFile("add-movie.json"))); 489 | 490 | stubFor(delete(urlPathMatching("/movieservice/v1/movieName/.*")) 491 | .willReturn(WireMock.ok())); 492 | 493 | String toyStoryCrew = "Tom Hanks, Tim Allen"; 494 | Movie toyStory = new Movie(null, "Toy Story 5", 2019, toyStoryCrew, LocalDate.of(2019, 06, 20)); 495 | Movie movie = moviesRestClient.addNewMovie(toyStory); 496 | 497 | //when 498 | String responseMessage = moviesRestClient.deleteMovieByName(movie.getName()); 499 | 500 | //then 501 | assertEquals("Movie Deleted SuccessFully", responseMessage); 502 | 503 | verify(postRequestedFor(urlPathEqualTo(ADD_MOVIE_V1)) 504 | .withRequestBody(matchingJsonPath("$.name", equalTo("Toy Story 5")))); 505 | verify(deleteRequestedFor((urlPathMatching("/movieservice/v1/movieName/.*")))); 506 | verify(exactly(1), postRequestedFor(urlPathEqualTo(ADD_MOVIE_V1)) 507 | .withRequestBody(matchingJsonPath("$.name", equalTo("Toy Story 5")))); 508 | verify(moreThan(1), deleteRequestedFor((urlPathMatching("/movieservice/v1/movieName/.*")))); 509 | 510 | 511 | } 512 | 513 | @Test(expected = MovieErrorResponse.class) 514 | public void deleteMovieByName_NotFound() { 515 | 516 | //given 517 | String movieName = "ABC"; 518 | stubFor(delete(urlPathMatching("/movieservice/v1/movieName/.*")) 519 | .willReturn(WireMock.serverError())); 520 | 521 | 522 | //then 523 | moviesRestClient.deleteMovieByName(movieName); 524 | 525 | } 526 | 527 | } 528 | -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/404-invalid-input.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 400, 4 | "error": "Bad Request", 5 | "message": "Please pass all the input fields : [name, year]", 6 | "path": "/movieservice/v1/movie" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/404-movieId.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given Id - {{request.path.[3]}}", 6 | "path": "{{request.path}}" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/404-moviename.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given name - {{request.query.movie_name}}", 6 | "path": "/movieservice/v1/movie/100" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/404-movieyear.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given year - {{request.query.year}}", 6 | "path": "/movieservice/v1/movie/100" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/add-movie-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": 1, 3 | "name": "{{jsonPath request.body '$.name'}}", 4 | "year": "{{jsonPath request.body '$.year'}}", 5 | "cast": "{{jsonPath request.body '$.cast'}}", 6 | "release_date": "{{date parseDate(jsonPath request.body '$.release_date')}}" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/add-movie.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": 11, 3 | "name": "Toy Story 4", 4 | "year": 2019, 5 | "cast": "Tom Hanks, Tim Allen", 6 | "release_date": "2019-06-20" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/addmovie-invalidinput.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": null, 3 | "name": null, 4 | "year": null, 5 | "cast": "Tom Hanks, Tim Allen", 6 | "release_date": [ 7 | 2019, 8 | 6, 9 | 20 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/all-movies.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "movie_id": 1, 4 | "name": "Batman Begins", 5 | "year": 2005, 6 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 7 | "release_date": "2005-06-15" 8 | }, 9 | { 10 | "movie_id": 2, 11 | "name": "Dark Knight", 12 | "year": 2008, 13 | "cast": "Christian Bale, Heath Ledger , Michael Caine", 14 | "release_date": "2008-07-18" 15 | }, 16 | { 17 | "movie_id": 3, 18 | "name": "The Dark Knight Rises", 19 | "year": 2012, 20 | "cast": "Christian Bale, Heath Ledger , Michael Caine", 21 | "release_date": "2012-07-20" 22 | }, 23 | { 24 | "movie_id": 4, 25 | "name": "The Avengers", 26 | "year": 2012, 27 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 28 | "release_date": "2012-05-04" 29 | }, 30 | { 31 | "movie_id": 5, 32 | "name": "Avengers: Age of Ultron", 33 | "year": 2015, 34 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 35 | "release_date": "2015-05-01" 36 | }, 37 | { 38 | "movie_id": 6, 39 | "name": "Avengers: Infinity War", 40 | "year": 2018, 41 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 42 | "release_date": "2018-04-27" 43 | }, 44 | { 45 | "movie_id": 7, 46 | "name": "Avengers: End Game", 47 | "year": 2019, 48 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 49 | "release_date": "2019-04-26" 50 | }, 51 | { 52 | "movie_id": 8, 53 | "name": "The Hangover", 54 | "year": 2009, 55 | "cast": "Bradley Cooper, Ed Helms , Zach Galifianakis", 56 | "release_date": "2009-06-05" 57 | }, 58 | { 59 | "movie_id": 9, 60 | "name": "The Imitation Game", 61 | "year": 2014, 62 | "cast": "Benedict Cumberbatch, Keira Knightley", 63 | "release_date": "2014-12-25" 64 | }, 65 | { 66 | "movie_id": 10, 67 | "name": "The Departed", 68 | "year": 2006, 69 | "cast": "Leonardo DiCaprio, Matt Damon , Mark Wahlberg", 70 | "release_date": "2006-10-06" 71 | } 72 | ] -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/avengers.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "movie_id": 4, 4 | "name": "The Avengers", 5 | "year": 2012, 6 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 7 | "release_date": "2012-05-04" 8 | }, 9 | { 10 | "movie_id": 5, 11 | "name": "Avengers: Age of Ultron", 12 | "year": 2015, 13 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 14 | "release_date": "2015-05-01" 15 | }, 16 | { 17 | "movie_id": 6, 18 | "name": "Avengers: Infinity War", 19 | "year": 2018, 20 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 21 | "release_date": "2018-04-27" 22 | }, 23 | { 24 | "movie_id": 7, 25 | "name": "Avengers: End Game", 26 | "year": 2019, 27 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 28 | "release_date": "2019-04-26" 29 | } 30 | ] -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/movie-byname-template.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "movie_id": 4, 4 | "name": "The {{request.query.movie_name}}", 5 | "year": 2012, 6 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 7 | "release_date": "2012-05-04" 8 | }, 9 | { 10 | "movie_id": 5, 11 | "name": "{{request.query.movie_name}}: Age of Ultron", 12 | "year": 2015, 13 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 14 | "release_date": "2015-05-01" 15 | }, 16 | { 17 | "movie_id": 6, 18 | "name": "{{request.query.movie_name}}: Infinity War", 19 | "year": 2018, 20 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 21 | "release_date": "2018-04-27" 22 | }, 23 | { 24 | "movie_id": 7, 25 | "name": "{{request.query.movie_name}}: End Game", 26 | "year": 2019, 27 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 28 | "release_date": "2019-04-26" 29 | } 30 | ] -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/movie-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": "{{request.path.[3]}}", 3 | "name": "Batman Begins", 4 | "year": 2005, 5 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 6 | "release_date": "2005-06-15" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/movie.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": 1, 3 | "name": "Batman Begins", 4 | "year": 2005, 5 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 6 | "release_date": "2005-06-15" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/movie1.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": 1, 3 | "name": "Batman Begins1", 4 | "year": 2005, 5 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 6 | "release_date": "2005-06-15" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/updatemovie-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": "{{request.path.[3]}}", 3 | "name": "Batman Begins", 4 | "year": 2005, 5 | "cast": "Christian Bale, Heath Ledger , Michael Caine, {{jsonPath request.body '$.cast'}}", 6 | "release_date": "2005-06-15" 7 | } -------------------------------------------------------------------------------- /movie-app-boot/src/test/resources/__files/year-template.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "movie_id": 3, 4 | "name": "The Dark Knight Rises", 5 | "year": "{{request.query.year}}", 6 | "cast": "Christian Bale, Heath Ledger , Michael Caine", 7 | "release_date": "2012-07-20" 8 | }, 9 | { 10 | "movie_id": 4, 11 | "name": "The Avengers", 12 | "year": "{{request.query.year}}", 13 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 14 | "release_date": "2012-05-04" 15 | } 16 | ] -------------------------------------------------------------------------------- /movies-app-final/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | apply plugin: 'java' 5 | 6 | group 'com.learnwiremock' 7 | version '1.0-SNAPSHOT' 8 | 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | maven {url "https://jitpack.io"} 14 | 15 | 16 | } 17 | 18 | test{ 19 | useJUnitPlatform() 20 | } 21 | 22 | dependencies { 23 | //webclient-dependencies 24 | implementation 'org.springframework:spring-webflux:5.1.8.RELEASE' 25 | implementation 'io.projectreactor.netty:reactor-netty:0.8.9.RELEASE' 26 | 27 | //lombok 28 | compileOnly 'org.projectlombok:lombok:1.18.8' 29 | annotationProcessor 'org.projectlombok:lombok:1.18.8' 30 | implementation 'org.slf4j:slf4j-api:1.7.26' 31 | implementation 'org.slf4j:slf4j-simple:1.7.26' 32 | 33 | //jackson 34 | implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.9' 35 | implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9' 36 | implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.9' 37 | implementation 'com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.9' 38 | 39 | //junit5-dependencies 40 | testImplementation("org.junit.jupiter:junit-jupiter-engine:5.5.1") 41 | 42 | //wiremock 43 | testImplementation "com.github.tomakehurst:wiremock-jre8-standalone:2.24.1" 44 | implementation "com.github.JensPiegsa:wiremock-extension:0.4.0" 45 | } 46 | 47 | -------------------------------------------------------------------------------- /movies-app-final/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dilipsundarraj1/wiremock-for-java-developers/3321de471628cb58641f5aa021503dd5ff791872/movies-app-final/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /movies-app-final/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Sep 03 06:08:44 CDT 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /movies-app-final/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /movies-app-final/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /movies-app-final/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'movies-app' 2 | 3 | -------------------------------------------------------------------------------- /movies-app-final/src/main/java/com/learnwiremock/constants/MoviesAppConstants.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.constants; 2 | 3 | import org.springframework.web.util.UriBuilder; 4 | 5 | import java.net.URI; 6 | import java.util.function.Function; 7 | 8 | public class MoviesAppConstants { 9 | 10 | public static final String GET_ALL_MOVIES_V1 = "/movieservice/v1/allMovies"; 11 | public static final String MOVIE_BY_ID_PATH_PARAM_V1 = "/movieservice/v1/movie/{id}"; 12 | public static final String MOVIE_BY_NAME_QUERY_PARAM_V1 = "/movieservice/v1/movieName"; 13 | public static final String MOVIE_BY_YEAR_QUERY_PARAM_V1 ="/movieservice/v1/movieYear"; 14 | public static final String ADD_MOVIE_V1 ="/movieservice/v1/movie"; 15 | } 16 | -------------------------------------------------------------------------------- /movies-app-final/src/main/java/com/learnwiremock/dto/Movie.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.time.LocalDate; 8 | 9 | @Data 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class Movie { 13 | 14 | public Double movie_id; 15 | public String name; 16 | public String cast; 17 | public Integer year; 18 | public LocalDate release_date; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /movies-app-final/src/main/java/com/learnwiremock/exception/MovieErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.exception; 2 | 3 | import org.springframework.web.reactive.function.client.WebClientResponseException; 4 | 5 | public class MovieErrorResponse extends RuntimeException { 6 | public MovieErrorResponse(String statusText, WebClientResponseException ex) { 7 | super(statusText,ex); 8 | } 9 | 10 | public MovieErrorResponse(Exception ex) { 11 | super(ex); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /movies-app-final/src/main/java/com/learnwiremock/service/MoviesRestClient.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.learnwiremock.constants.MoviesAppConstants; 4 | import com.learnwiremock.dto.Movie; 5 | import com.learnwiremock.exception.MovieErrorResponse; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.web.reactive.function.client.WebClient; 8 | import org.springframework.web.reactive.function.client.WebClientResponseException; 9 | import org.springframework.web.util.UriComponentsBuilder; 10 | 11 | import java.util.List; 12 | 13 | import static com.learnwiremock.constants.MoviesAppConstants.MOVIE_BY_ID_PATH_PARAM_V1; 14 | 15 | 16 | @Slf4j 17 | public class MoviesRestClient { 18 | 19 | private WebClient webClient; 20 | 21 | public MoviesRestClient(WebClient webClient) { 22 | this.webClient = webClient; 23 | } 24 | 25 | public List retrieveAllMovies() { 26 | 27 | //http://localhost:8081/movieservice/v1/allMovies 28 | try { 29 | return webClient.get().uri(MoviesAppConstants.GET_ALL_MOVIES_V1) 30 | .retrieve() 31 | .bodyToFlux(Movie.class) 32 | .collectList() 33 | .block(); 34 | } catch (WebClientResponseException ex) { 35 | log.error("WebClientResponseException in retrieveAllMovies. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 36 | throw new MovieErrorResponse(ex.getStatusText(), ex); 37 | } catch (Exception ex) { 38 | log.error("Exception in retrieveAllMovies and the message is {} ", ex.getMessage() + ex); 39 | throw new MovieErrorResponse(ex); 40 | } 41 | } 42 | 43 | public Movie retrieveMovieById(Integer movieId) { 44 | 45 | //http://localhost:8081/movieservice/v1/movie/100 46 | try { 47 | return webClient.get().uri(MOVIE_BY_ID_PATH_PARAM_V1, movieId) 48 | .retrieve() 49 | .bodyToMono(Movie.class) 50 | .block(); 51 | } catch (WebClientResponseException ex) { 52 | log.error("WebClientResponseException in retrieveMovieById. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 53 | throw new MovieErrorResponse(ex.getStatusText(), ex); 54 | } catch (Exception ex) { 55 | log.error("Exception in retrieveMovieById and the message is {} ", ex); 56 | throw new MovieErrorResponse(ex); 57 | } 58 | } 59 | 60 | public List retrieveMoviebyName(String name) { 61 | 62 | // http://localhost:8081/movieservice/v1/movieName?movie_name=ABC 63 | 64 | String retrieveByNameUri = UriComponentsBuilder.fromUriString(MoviesAppConstants.MOVIE_BY_NAME_QUERY_PARAM_V1) 65 | .queryParam("movie_name", name) 66 | .buildAndExpand() 67 | .toUriString(); 68 | try { 69 | return webClient.get().uri(retrieveByNameUri) 70 | .retrieve() 71 | .bodyToFlux(Movie.class) 72 | .collectList() 73 | .block(); 74 | } catch (WebClientResponseException ex) { 75 | log.error("WebClientResponseException in retrieveMoviebyName. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 76 | throw new MovieErrorResponse(ex.getStatusText(), ex); 77 | } catch (Exception ex) { 78 | log.error("Exception in retrieveMoviebyName and the message is {} ", ex); 79 | throw new MovieErrorResponse(ex); 80 | } 81 | 82 | } 83 | 84 | public List retrieveMoviebyYear(Integer movieYear) { 85 | 86 | // http://localhost:8081/movieservice/v1/movieYear?year=1950 87 | 88 | String retrieveByNameUri = UriComponentsBuilder.fromUriString(MoviesAppConstants.MOVIE_BY_YEAR_QUERY_PARAM_V1) 89 | .queryParam("year", movieYear) 90 | .buildAndExpand() 91 | .toUriString(); 92 | try { 93 | return webClient.get().uri(retrieveByNameUri) 94 | .retrieve() 95 | .bodyToFlux(Movie.class) 96 | .collectList() 97 | .block(); 98 | } catch (WebClientResponseException ex) { 99 | log.error("WebClientResponseException in retrieveMoviebyYear. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 100 | throw new MovieErrorResponse(ex.getStatusText(), ex); 101 | } catch (Exception ex) { 102 | log.error("Exception in retrieveMoviebyYear and the message is {} ", ex); 103 | throw new MovieErrorResponse(ex); 104 | } 105 | 106 | } 107 | 108 | public Movie addMovie( Movie newMovie){ 109 | 110 | //http://localhost:8081/movieservice/v1/movie 111 | try { 112 | return webClient.post().uri(MoviesAppConstants.ADD_MOVIE_V1) 113 | .syncBody(newMovie) 114 | .retrieve() 115 | .bodyToMono(Movie.class) 116 | .block(); 117 | } catch (WebClientResponseException ex) { 118 | log.error("WebClientResponseException in addMovie. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 119 | throw new MovieErrorResponse(ex.getStatusText(), ex); 120 | } catch (Exception ex) { 121 | log.error("Exception in addMovie and the message is {} ", ex); 122 | throw new MovieErrorResponse(ex); 123 | } 124 | 125 | } 126 | 127 | 128 | public Movie updateMovie(Integer movieId, Movie movie){ 129 | try { 130 | return webClient.put().uri(MOVIE_BY_ID_PATH_PARAM_V1, movieId) 131 | .syncBody(movie) 132 | .retrieve() 133 | .bodyToMono(Movie.class) 134 | .block(); 135 | }catch (WebClientResponseException ex) { 136 | log.error("WebClientResponseException in updateMovie. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 137 | throw new MovieErrorResponse(ex.getStatusText(), ex); 138 | } catch (Exception ex) { 139 | log.error("Exception in updateMovie and the message is {} ", ex); 140 | throw new MovieErrorResponse(ex); 141 | } 142 | 143 | } 144 | 145 | public String deleteMovie(Integer movieId){ 146 | 147 | try{ 148 | return webClient.delete().uri(MOVIE_BY_ID_PATH_PARAM_V1, movieId) 149 | .retrieve() 150 | .bodyToMono(String.class) 151 | .block(); 152 | 153 | }catch (WebClientResponseException ex) { 154 | log.error("WebClientResponseException in deleteMovie. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 155 | throw new MovieErrorResponse(ex.getStatusText(), ex); 156 | } catch (Exception ex) { 157 | log.error("Exception in deleteMovie and the message is {} ", ex); 158 | throw new MovieErrorResponse(ex); 159 | } 160 | } 161 | 162 | public String deleteMovieByName(String movieName){ 163 | 164 | try{ 165 | String deleteMovieByNameURI = UriComponentsBuilder.fromUriString(MoviesAppConstants.MOVIE_BY_NAME_QUERY_PARAM_V1) 166 | .queryParam("movie_name", movieName) 167 | .buildAndExpand() 168 | .toUriString(); 169 | 170 | webClient.delete().uri(deleteMovieByNameURI) 171 | .retrieve() 172 | .bodyToMono(Void.class) 173 | .block(); 174 | 175 | }catch (WebClientResponseException ex) { 176 | log.error("WebClientResponseException in deleteMovie. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 177 | throw new MovieErrorResponse(ex.getStatusText(), ex); 178 | } catch (Exception ex) { 179 | log.error("Exception in deleteMovie and the message is {} ", ex); 180 | throw new MovieErrorResponse(ex); 181 | } 182 | 183 | return "Movie Deleted Successfully"; 184 | } 185 | 186 | } 187 | -------------------------------------------------------------------------------- /movies-app-final/src/test/java/com/learnwiremock/service/MoviesRestClientServerFaultTest.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.github.jenspiegsa.wiremockextension.ConfigureWireMock; 4 | import com.github.jenspiegsa.wiremockextension.InjectServer; 5 | import com.github.jenspiegsa.wiremockextension.WireMockExtension; 6 | import com.github.tomakehurst.wiremock.WireMockServer; 7 | import com.github.tomakehurst.wiremock.client.WireMock; 8 | import com.github.tomakehurst.wiremock.common.ConsoleNotifier; 9 | import com.github.tomakehurst.wiremock.core.Options; 10 | import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; 11 | import com.github.tomakehurst.wiremock.http.Fault; 12 | import com.learnwiremock.dto.Movie; 13 | import com.learnwiremock.exception.MovieErrorResponse; 14 | import io.netty.channel.Channel; 15 | import io.netty.channel.ChannelOption; 16 | import io.netty.handler.timeout.ReadTimeoutHandler; 17 | import io.netty.handler.timeout.WriteTimeoutHandler; 18 | import org.junit.jupiter.api.Assertions; 19 | import org.junit.jupiter.api.BeforeEach; 20 | import org.junit.jupiter.api.Test; 21 | import org.junit.jupiter.api.extension.ExtendWith; 22 | import org.springframework.http.HttpHeaders; 23 | import org.springframework.http.HttpStatus; 24 | import org.springframework.http.MediaType; 25 | import org.springframework.http.client.reactive.ReactorClientHttpConnector; 26 | import org.springframework.web.reactive.function.client.WebClient; 27 | import reactor.netty.http.client.HttpClient; 28 | import reactor.netty.tcp.TcpClient; 29 | 30 | import java.util.List; 31 | 32 | import static com.github.tomakehurst.wiremock.client.WireMock.*; 33 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; 34 | import static org.junit.jupiter.api.Assertions.*; 35 | 36 | @ExtendWith(WireMockExtension.class) 37 | public class MoviesRestClientServerFaultTest { 38 | 39 | MoviesRestClient moviesRestClient; 40 | WebClient webClient; 41 | 42 | @InjectServer 43 | WireMockServer wireMockServer; 44 | 45 | @ConfigureWireMock 46 | Options options = wireMockConfig(). 47 | port(8088) 48 | .notifier(new ConsoleNotifier(true)) 49 | .extensions(new ResponseTemplateTransformer(true)); 50 | 51 | TcpClient tcpClient = TcpClient.create() 52 | .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) 53 | .doOnConnected(connection -> { 54 | connection.addHandlerLast(new ReadTimeoutHandler(5)) 55 | .addHandlerLast(new WriteTimeoutHandler(5)); 56 | }); 57 | 58 | @BeforeEach 59 | void setUp() { 60 | int port = wireMockServer.port(); 61 | String baseUrl = String.format("http://localhost:%s/", port); 62 | System.out.println("baseUrl : " + baseUrl); 63 | //webClient = WebClient.create(baseUrl); 64 | webClient = WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient))) 65 | .baseUrl(baseUrl).build(); 66 | moviesRestClient = new MoviesRestClient(webClient); 67 | } 68 | 69 | @Test 70 | void retrieveAllMovies() { 71 | 72 | //given 73 | stubFor(get(anyUrl()) 74 | .willReturn(serverError())); 75 | 76 | //then 77 | assertThrows(MovieErrorResponse.class, ()->moviesRestClient.retrieveAllMovies()); 78 | 79 | } 80 | 81 | @Test 82 | void retrieveAllMovies_503_serviceUnAvailable() { 83 | 84 | //given 85 | stubFor(get(anyUrl()) 86 | .willReturn(serverError() 87 | .withStatus(HttpStatus.SERVICE_UNAVAILABLE.value()) 88 | .withBody("Service Unavailable"))); 89 | 90 | //then 91 | MovieErrorResponse movieErrorResponse = assertThrows(MovieErrorResponse.class, ()->moviesRestClient.retrieveAllMovies()); 92 | assertEquals("Service Unavailable", movieErrorResponse.getMessage()); 93 | 94 | } 95 | 96 | @Test 97 | void retrieveAllMovies_FaultResponse() { 98 | 99 | //given 100 | stubFor(get(anyUrl()) 101 | .willReturn(aResponse().withFault(Fault.EMPTY_RESPONSE))); 102 | 103 | //then 104 | MovieErrorResponse movieErrorResponse = assertThrows(MovieErrorResponse.class, ()->moviesRestClient.retrieveAllMovies()); 105 | String errorMessage="reactor.core.Exceptions$ReactiveException: reactor.netty.http.client.PrematureCloseException: Connection prematurely closed BEFORE response"; 106 | assertEquals(errorMessage, movieErrorResponse.getMessage()); 107 | 108 | } 109 | 110 | @Test 111 | void retrieveAllMovies_RandomDataThenClose() { 112 | 113 | //given 114 | stubFor(get(anyUrl()) 115 | .willReturn(aResponse().withFault(Fault.RANDOM_DATA_THEN_CLOSE))); 116 | 117 | //then 118 | assertThrows(MovieErrorResponse.class, ()->moviesRestClient.retrieveAllMovies()); 119 | 120 | } 121 | 122 | @Test 123 | void retrieveAllMovies_fixedDelay() { 124 | 125 | //given 126 | stubFor(get(anyUrl()) 127 | .willReturn(ok().withFixedDelay(10000))); 128 | 129 | //then 130 | assertThrows(MovieErrorResponse.class, ()->moviesRestClient.retrieveAllMovies()); 131 | 132 | } 133 | 134 | @Test 135 | void retrieveAllMovies_RandomDelay() { 136 | 137 | //given 138 | stubFor(get(anyUrl()) 139 | .willReturn(ok().withUniformRandomDelay(6000,10000))); 140 | 141 | //then 142 | assertThrows(MovieErrorResponse.class, ()->moviesRestClient.retrieveAllMovies()); 143 | 144 | } 145 | 146 | } 147 | 148 | -------------------------------------------------------------------------------- /movies-app-final/src/test/java/com/learnwiremock/service/MoviesRestClientTest.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.github.jenspiegsa.wiremockextension.ConfigureWireMock; 4 | import com.github.jenspiegsa.wiremockextension.InjectServer; 5 | import com.github.jenspiegsa.wiremockextension.WireMockExtension; 6 | import com.github.tomakehurst.wiremock.WireMockServer; 7 | import com.github.tomakehurst.wiremock.client.WireMock; 8 | import com.github.tomakehurst.wiremock.common.ConsoleNotifier; 9 | import com.github.tomakehurst.wiremock.core.Options; 10 | import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; 11 | import com.learnwiremock.constants.MoviesAppConstants; 12 | import com.learnwiremock.dto.Movie; 13 | import com.learnwiremock.exception.MovieErrorResponse; 14 | import org.junit.jupiter.api.Assertions; 15 | import org.junit.jupiter.api.BeforeEach; 16 | import org.junit.jupiter.api.Test; 17 | import org.junit.jupiter.api.extension.ExtendWith; 18 | import org.springframework.http.HttpHeaders; 19 | import org.springframework.http.HttpStatus; 20 | import org.springframework.http.MediaType; 21 | import org.springframework.web.reactive.function.client.WebClient; 22 | import org.springframework.web.reactive.function.client.WebClientResponseException; 23 | 24 | import java.time.LocalDate; 25 | import java.util.List; 26 | import java.util.Random; 27 | 28 | import static com.github.tomakehurst.wiremock.client.WireMock.*; 29 | import static com.github.tomakehurst.wiremock.client.WireMock.verify; 30 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; 31 | import static com.learnwiremock.constants.MoviesAppConstants.*; 32 | import static org.junit.jupiter.api.Assertions.assertEquals; 33 | import static org.junit.jupiter.api.Assertions.assertTrue; 34 | 35 | @ExtendWith(WireMockExtension.class) 36 | public class MoviesRestClientTest { 37 | 38 | MoviesRestClient moviesRestClient; 39 | WebClient webClient; 40 | 41 | @InjectServer 42 | WireMockServer wireMockServer; 43 | 44 | @ConfigureWireMock 45 | Options options = wireMockConfig(). 46 | port(8088) 47 | .notifier(new ConsoleNotifier(true)) 48 | .extensions(new ResponseTemplateTransformer(true)); 49 | 50 | @BeforeEach 51 | void setUp() { 52 | int port = wireMockServer.port(); 53 | String baseUrl = String.format("http://localhost:%s/", port); 54 | System.out.println("baseUrl : " + baseUrl); 55 | webClient = WebClient.create(baseUrl); 56 | moviesRestClient = new MoviesRestClient(webClient); 57 | 58 | stubFor(any(anyUrl()).willReturn(aResponse().proxiedFrom("http://localhost:8081"))); 59 | } 60 | 61 | @Test 62 | void retrieveAllMovies() { 63 | 64 | //given 65 | stubFor(get(anyUrl()) 66 | .willReturn(WireMock.aResponse() 67 | .withStatus(HttpStatus.OK.value()) 68 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 69 | .withBodyFile("all-movies.json"))); 70 | 71 | //when 72 | List movieList = moviesRestClient.retrieveAllMovies(); 73 | System.out.println("movieList : " + movieList); 74 | 75 | //then 76 | assertTrue(movieList.size() > 0); 77 | } 78 | 79 | @Test 80 | void retrieveAllMovies_matchesUrl() { 81 | 82 | //given 83 | stubFor(get(urlPathEqualTo(MoviesAppConstants.GET_ALL_MOVIES_V1)) 84 | .willReturn(WireMock.aResponse() 85 | .withStatus(HttpStatus.OK.value()) 86 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 87 | .withBodyFile("all-movies.json"))); 88 | 89 | //when 90 | List movieList = moviesRestClient.retrieveAllMovies(); 91 | System.out.println("movieList : " + movieList); 92 | 93 | //then 94 | assertTrue(movieList.size() > 0); 95 | } 96 | 97 | 98 | @Test 99 | void retrieveMovieById() { 100 | //given 101 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]")) 102 | .willReturn(WireMock.aResponse() 103 | .withStatus(HttpStatus.OK.value()) 104 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 105 | .withBodyFile("movie.json"))); 106 | Integer movieId = 9; 107 | 108 | //when 109 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 110 | 111 | //then 112 | assertEquals("Batman Begins", movie.getName()); 113 | 114 | } 115 | 116 | @Test 117 | void retrieveMovieById_reponseTemplating() { 118 | //given 119 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]")) 120 | .willReturn(WireMock.aResponse() 121 | .withStatus(HttpStatus.OK.value()) 122 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 123 | .withBodyFile("movie-template.json"))); 124 | Integer movieId = 8; 125 | 126 | //when 127 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 128 | System.out.println("movie : " + movie); 129 | 130 | //then 131 | assertEquals("Batman Begins", movie.getName()); 132 | assertEquals(8, movie.getMovie_id().intValue()); 133 | 134 | } 135 | 136 | 137 | @Test 138 | void retrieveMovieById_notFound() { 139 | //given 140 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 141 | .willReturn(WireMock.aResponse() 142 | .withStatus(HttpStatus.NOT_FOUND.value()) 143 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 144 | .withBodyFile("404-movieId.json"))); 145 | Integer movieId = 100; 146 | 147 | //when 148 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.retrieveMovieById(movieId)); 149 | 150 | } 151 | 152 | @Test 153 | void retrieveMoviebyName() { 154 | 155 | //given 156 | String movieName = "Avengers"; 157 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name="+movieName)) 158 | .willReturn(WireMock.aResponse() 159 | .withStatus(HttpStatus.OK.value()) 160 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 161 | .withBodyFile("avengers.json"))); 162 | 163 | 164 | //when 165 | List movieList = moviesRestClient.retrieveMoviebyName(movieName); 166 | 167 | //then 168 | String castExpected = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 169 | assertEquals(4, movieList.size()); 170 | assertEquals(castExpected, movieList.get(0).getCast()); 171 | 172 | } 173 | 174 | @Test 175 | void retrieveMoviebyName_responeTemplating() { 176 | 177 | //given 178 | String movieName = "Avengers"; 179 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name="+movieName)) 180 | .willReturn(WireMock.aResponse() 181 | .withStatus(HttpStatus.OK.value()) 182 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 183 | .withBodyFile("movie-byName-template.json"))); 184 | 185 | 186 | //when 187 | List movieList = moviesRestClient.retrieveMoviebyName(movieName); 188 | 189 | //then 190 | String castExpected = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 191 | assertEquals(4, movieList.size()); 192 | assertEquals(castExpected, movieList.get(0).getCast()); 193 | 194 | } 195 | 196 | 197 | @Test 198 | void retrieveMoviebyName_approach2() { 199 | 200 | //given 201 | String movieName = "Avengers"; 202 | stubFor(get(urlPathEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1)) 203 | // .withQueryParam("movie_name", equalTo(movieName) ) 204 | .willReturn(WireMock.aResponse() 205 | .withStatus(HttpStatus.OK.value()) 206 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 207 | .withBodyFile("avengers.json"))); 208 | 209 | 210 | //when 211 | List movieList = moviesRestClient.retrieveMoviebyName(movieName); 212 | 213 | //then 214 | String castExpected = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 215 | assertEquals(4, movieList.size()); 216 | assertEquals(castExpected, movieList.get(0).getCast()); 217 | 218 | } 219 | 220 | @Test 221 | void retrieveMoviebyName_Not_Found() { 222 | 223 | //given 224 | String movieName = "ABC"; 225 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name="+movieName)) 226 | .willReturn(WireMock.aResponse() 227 | .withStatus(HttpStatus.NOT_FOUND.value()) 228 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 229 | .withBodyFile("404-movieName.json"))); 230 | 231 | 232 | //when 233 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.retrieveMoviebyName(movieName)); 234 | 235 | } 236 | 237 | @Test 238 | void retrieveMoviebyYear() { 239 | //given 240 | Integer year = 2012; 241 | stubFor(get(urlEqualTo(MOVIE_BY_YEAR_QUERY_PARAM_V1+"?year="+year)) 242 | .willReturn(WireMock.aResponse() 243 | .withStatus(HttpStatus.OK.value()) 244 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 245 | .withBodyFile("year-template.json"))); 246 | 247 | //when 248 | List movieList = moviesRestClient.retrieveMoviebyYear(year); 249 | 250 | //then 251 | assertEquals(2, movieList.size()); 252 | 253 | } 254 | 255 | @Test 256 | void retrieveMoviebyYear_not_found() { 257 | //given 258 | Integer year = 1950; 259 | stubFor(get(urlEqualTo(MOVIE_BY_YEAR_QUERY_PARAM_V1+"?year="+year)) 260 | .withQueryParam("year", equalTo(year.toString())) 261 | .willReturn(WireMock.aResponse() 262 | .withStatus(HttpStatus.NOT_FOUND.value()) 263 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 264 | .withBodyFile("404-movieyear.json"))); 265 | 266 | //when 267 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.retrieveMoviebyYear(year)); 268 | 269 | } 270 | 271 | @Test 272 | void addMovie() { 273 | //given 274 | Movie movie = new Movie(null, "Toys Story 4", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 275 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 276 | // .withQueryParam("movie_name", equalTo(movieName) ) 277 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 4"))) 278 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 279 | .willReturn(WireMock.aResponse() 280 | .withStatus(HttpStatus.OK.value()) 281 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 282 | .withBodyFile("add-movie.json"))); 283 | 284 | //when 285 | Movie addedMovie = moviesRestClient.addMovie(movie); 286 | System.out.println(addedMovie); 287 | 288 | //then 289 | assertTrue(addedMovie.getMovie_id() != null); 290 | } 291 | 292 | @Test 293 | void addMovie_responseTemplating() { 294 | //given 295 | Movie movie = new Movie(null, "Toys Story 4", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 296 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 297 | // .withQueryParam("movie_name", equalTo(movieName) ) 298 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 4"))) 299 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 300 | .willReturn(WireMock.aResponse() 301 | .withStatus(HttpStatus.OK.value()) 302 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 303 | .withTransformers("Random-Value") 304 | .withTransformerParameter("id", new Random().nextDouble()) 305 | .withBodyFile("add-movie-template.json"))); 306 | 307 | //when 308 | Movie addedMovie = moviesRestClient.addMovie(movie); 309 | System.out.println(addedMovie); 310 | 311 | //then 312 | assertTrue(addedMovie.getMovie_id() != null); 313 | } 314 | 315 | @Test 316 | void addMovie_responseTemplating_approach1() { 317 | //given 318 | Movie movie = new Movie(null, "Toys Story 4", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 319 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 320 | // .withQueryParam("movie_name", equalTo(movieName) ) 321 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 4"))) 322 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 323 | .willReturn(WireMock.aResponse() 324 | .withStatus(HttpStatus.OK.value()) 325 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 326 | .withTransformers("Random-Value") 327 | .withTransformerParameter("id", new Random().nextDouble()) 328 | .withBodyFile("add-movie-template-approach1.json"))); 329 | 330 | //when 331 | Movie addedMovie = moviesRestClient.addMovie(movie); 332 | System.out.println(addedMovie); 333 | 334 | //then 335 | assertTrue(addedMovie.getMovie_id() != null); 336 | } 337 | 338 | @Test 339 | void addMovie_badRequest() { 340 | //given 341 | Movie movie = new Movie(null, null, "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 342 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 343 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 344 | .willReturn(WireMock.aResponse() 345 | .withStatus(HttpStatus.BAD_REQUEST.value()) 346 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 347 | .withBodyFile("400-invalid-input.json"))); 348 | 349 | //when 350 | String expectedErrorMessage = "Please pass all the input fields : [name]"; 351 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.addMovie(movie), expectedErrorMessage); 352 | } 353 | 354 | @Test 355 | void updateMovie() { 356 | //given 357 | Integer movieId = 3; 358 | String cast = "ABC"; 359 | Movie movie = new Movie(null, null, cast, null, null); 360 | stubFor(put(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 361 | .withRequestBody(matchingJsonPath(("$.cast"), containing(cast))) 362 | .willReturn(WireMock.aResponse() 363 | .withStatus(HttpStatus.OK.value()) 364 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 365 | .withBodyFile("updatemovie-template.json"))); 366 | 367 | //when 368 | Movie updatedMovie = moviesRestClient.updateMovie(movieId, movie); 369 | 370 | //then 371 | assertTrue(updatedMovie.getCast().contains(cast)); 372 | } 373 | 374 | @Test 375 | void updateMovie_notFound() { 376 | //given 377 | Integer movieId = 100; 378 | String cast = "ABC"; 379 | Movie movie = new Movie(null, null, cast, null, null); 380 | stubFor(put(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 381 | .withRequestBody(matchingJsonPath(("$.cast"), containing(cast))) 382 | .willReturn(WireMock.aResponse() 383 | .withStatus(HttpStatus.NOT_FOUND.value()) 384 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 385 | 386 | 387 | //then 388 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.updateMovie(movieId, movie)); 389 | } 390 | 391 | @Test 392 | void deleteMovie() { 393 | //given 394 | Movie movie = new Movie(null, "Toys Story 5", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 395 | 396 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 397 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 5"))) 398 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 399 | .willReturn(WireMock.aResponse() 400 | .withStatus(HttpStatus.OK.value()) 401 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 402 | .withBodyFile("add-movie-template.json"))); 403 | Movie addedMovie = moviesRestClient.addMovie(movie); 404 | 405 | String expectedErrorMessage = "Movie Deleted Successfully"; 406 | stubFor(delete(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 407 | .willReturn(WireMock.aResponse() 408 | .withStatus(HttpStatus.OK.value()) 409 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 410 | .withBody(expectedErrorMessage))); 411 | 412 | //when 413 | String responseMessage = moviesRestClient.deleteMovie(addedMovie.getMovie_id().intValue()); 414 | 415 | //then 416 | assertEquals(expectedErrorMessage, responseMessage); 417 | } 418 | 419 | @Test 420 | void deleteMovie_NotFound() { 421 | //given 422 | Integer id = 100; 423 | stubFor(delete(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 424 | .willReturn(WireMock.aResponse() 425 | .withStatus(HttpStatus.NOT_FOUND.value()) 426 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 427 | 428 | //then 429 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.deleteMovie(id)); 430 | 431 | } 432 | 433 | 434 | @Test 435 | void deleteMovieByName() { 436 | //given 437 | Movie movie = new Movie(null, "Toys Story 5", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 438 | 439 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 440 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 5"))) 441 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 442 | .willReturn(WireMock.aResponse() 443 | .withStatus(HttpStatus.OK.value()) 444 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 445 | .withBodyFile("add-movie-template.json"))); 446 | Movie addedMovie = moviesRestClient.addMovie(movie); 447 | 448 | String expectedErrorMessage = "Movie Deleted Successfully"; 449 | stubFor(delete(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name=Toys%20Story%205")) 450 | .willReturn(WireMock.aResponse() 451 | .withStatus(HttpStatus.OK.value()) 452 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 453 | 454 | //when 455 | String responseMessage = moviesRestClient.deleteMovieByName(addedMovie.getName()); 456 | 457 | //then 458 | assertEquals(expectedErrorMessage, responseMessage); 459 | 460 | verify(exactly(1),postRequestedFor(urlPathEqualTo(ADD_MOVIE_V1)) 461 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 5"))) 462 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom")))); 463 | 464 | verify(exactly(1),deleteRequestedFor(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name=Toys%20Story%205"))); 465 | 466 | } 467 | 468 | //@Test 469 | void deleteMovieByName_selectiveproxying() { 470 | //given 471 | Movie movie = new Movie(null, "Toys Story 5", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 472 | Movie addedMovie = moviesRestClient.addMovie(movie); 473 | 474 | String expectedErrorMessage = "Movie Deleted Successfully"; 475 | stubFor(delete(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name=Toys%20Story%205")) 476 | .willReturn(WireMock.aResponse() 477 | .withStatus(HttpStatus.OK.value()) 478 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 479 | 480 | //when 481 | String responseMessage = moviesRestClient.deleteMovieByName(addedMovie.getName()); 482 | 483 | //then 484 | assertEquals(expectedErrorMessage, responseMessage); 485 | 486 | verify(exactly(1),deleteRequestedFor(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name=Toys%20Story%205"))); 487 | 488 | } 489 | } 490 | 491 | -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/400-invalid-input.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 400, 4 | "error": "Bad Request", 5 | "message": "Please pass all the input fields : [name]", 6 | "path": "{{request.path}}" 7 | } 8 | -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/404-movieId.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given Id - {{request.path.[3]}}", 6 | "path": "{{request.path}}" 7 | } 8 | -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/404-movieName.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given name - {{request.query.movie_name}}", 6 | "path": "{{request.path}}" 7 | } -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/404-moviename.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given name - {{request.query.movie_name}}", 6 | "path": "{{request.path}}" 7 | } -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/404-movieyear.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given year - {{request.query.year}}", 6 | "path": "{{request.path}}" 7 | } -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/add-movie-template-approach1.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": "{{parameters.id}}", 3 | "name": "{{jsonPath request.body '$.name'}}", 4 | "year": "{{jsonPath request.body '$.year'}}", 5 | "cast": "{{jsonPath request.body '$.cast'}}", 6 | "release_date": "{{date parseDate(jsonPath request.body '$.release_date')}}" 7 | } -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/add-movie-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": "{{randomValue length=2 type='NUMERIC'}}", 3 | "name": "{{jsonPath request.body '$.name'}}", 4 | "year": "{{jsonPath request.body '$.year'}}", 5 | "cast": "{{jsonPath request.body '$.cast'}}", 6 | "release_date": "{{date parseDate(jsonPath request.body '$.release_date')}}" 7 | } -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/add-movie.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": 11, 3 | "name": "Toys Story 4", 4 | "year": 2019, 5 | "cast": "Tom Hanks, Tim Allen", 6 | "release_date": "2019-06-20" 7 | } -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/all-movies.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "movie_id": 1, 4 | "name": "Batman Begins", 5 | "year": 2005, 6 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 7 | "release_date": "2005-06-15" 8 | }, 9 | { 10 | "movie_id": 2, 11 | "name": "Dark Knight", 12 | "year": 2008, 13 | "cast": "Christian Bale, Heath Ledger , Michael Caine", 14 | "release_date": "2008-07-18" 15 | }, 16 | { 17 | "movie_id": 3, 18 | "name": "The Dark Knight Rises", 19 | "year": 2012, 20 | "cast": "Christian Bale, Heath Ledger , Michael Caine", 21 | "release_date": "2012-07-20" 22 | }, 23 | { 24 | "movie_id": 4, 25 | "name": "The Avengers", 26 | "year": 2012, 27 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 28 | "release_date": "2012-05-04" 29 | }, 30 | { 31 | "movie_id": 5, 32 | "name": "Avengers: Age of Ultron", 33 | "year": 2015, 34 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 35 | "release_date": "2015-05-01" 36 | }, 37 | { 38 | "movie_id": 6, 39 | "name": "Avengers: Infinity War", 40 | "year": 2018, 41 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 42 | "release_date": "2018-04-27" 43 | }, 44 | { 45 | "movie_id": 7, 46 | "name": "Avengers: End Game", 47 | "year": 2019, 48 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 49 | "release_date": "2019-04-26" 50 | }, 51 | { 52 | "movie_id": 8, 53 | "name": "The Hangover", 54 | "year": 2009, 55 | "cast": "Bradley Cooper, Ed Helms , Zach Galifianakis", 56 | "release_date": "2009-06-05" 57 | }, 58 | { 59 | "movie_id": 9, 60 | "name": "The Imitation Game", 61 | "year": 2014, 62 | "cast": "Benedict Cumberbatch, Keira Knightley", 63 | "release_date": "2014-12-25" 64 | }, 65 | { 66 | "movie_id": 10, 67 | "name": "The Departed", 68 | "year": 2006, 69 | "cast": "Leonardo DiCaprio, Matt Damon , Mark Wahlberg", 70 | "release_date": "2006-10-06" 71 | } 72 | ] -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/avengers.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "movie_id": 4, 3 | "name": "The Avengers", 4 | "year": 2012, 5 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 6 | "release_date": "2012-05-04" 7 | }, 8 | { 9 | "movie_id": 5, 10 | "name": "Avengers: Age of Ultron", 11 | "year": 2015, 12 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 13 | "release_date": "2015-05-01" 14 | }, 15 | { 16 | "movie_id": 6, 17 | "name": "Avengers: Infinity War", 18 | "year": 2018, 19 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 20 | "release_date": "2018-04-27" 21 | }, 22 | { 23 | "movie_id": 7, 24 | "name": "Avengers: End Game", 25 | "year": 2019, 26 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 27 | "release_date": "2019-04-26" 28 | }] -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/movie-byName-template.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "movie_id": 4, 3 | "name": "The {{request.query.movie_name}}", 4 | "year": 2012, 5 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 6 | "release_date": "2012-05-04" 7 | }, 8 | { 9 | "movie_id": 5, 10 | "name": "{{request.query.movie_name}}: Age of Ultron", 11 | "year": 2015, 12 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 13 | "release_date": "2015-05-01" 14 | }, 15 | { 16 | "movie_id": 6, 17 | "name": "{{request.query.movie_name}}: Infinity War", 18 | "year": 2018, 19 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 20 | "release_date": "2018-04-27" 21 | }, 22 | { 23 | "movie_id": 7, 24 | "name": "{{request.query.movie_name}}: End Game", 25 | "year": 2019, 26 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 27 | "release_date": "2019-04-26" 28 | }] -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/movie-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": "{{request.path.[3]}}", 3 | "name": "Batman Begins", 4 | "year": 2005, 5 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 6 | "release_date": "2005-06-15" 7 | } -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/movie.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": 1, 3 | "name": "Batman Begins", 4 | "year": 2005, 5 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 6 | "release_date": "2005-06-15" 7 | } -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/updatemovie-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": "{{request.path.[3]}}", 3 | "name": "Toys Story 4", 4 | "year": 2019, 5 | "cast": "Tom Hanks, Tim Allen, {{jsonPath request.body '$.cast'}}", 6 | "release_date": "2019-06-20" 7 | } -------------------------------------------------------------------------------- /movies-app-final/src/test/resources/__files/year-template.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "movie_id": 3, 4 | "name": "The Dark Knight Rises", 5 | "year": "{{request.query.year}}", 6 | "cast": "Christian Bale, Heath Ledger , Michael Caine", 7 | "release_date": "2012-07-20" 8 | }, 9 | { 10 | "movie_id": 4, 11 | "name": "The Avengers", 12 | "year": "{{request.query.year}}", 13 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 14 | "release_date": "2012-05-04" 15 | } 16 | ] -------------------------------------------------------------------------------- /movies-app-junit4/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /nbdist/ 28 | /dist/ 29 | /out/ 30 | /.nb-gradle/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /movies-app-junit4/README.md: -------------------------------------------------------------------------------- 1 | # MovieApp 2 | 3 | - This is a application which connects to the Movies RESTFUL Service. 4 | 5 | ## How to enable JUnit5? 6 | 7 | - Please make the below changes to enable JUnit5 in your project. 8 | 9 | ### build.gradle 10 | 11 | - Add the below code to enable Junit5 as a test platform. 12 | 13 | ```youtrack 14 | test { 15 | useJUnitPlatform() // enables Junit5 16 | } 17 | ``` 18 | - Add this dependency to use the Junit% 19 | 20 | ```youtrack 21 | dependencies { 22 | //junit5-dependencies 23 | testImplementation('org.junit.jupiter:junit-jupiter:5.5.1') 24 | } 25 | ``` -------------------------------------------------------------------------------- /movies-app-junit4/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | apply plugin: 'java' 5 | 6 | group 'com.learnwiremock' 7 | version '1.0-SNAPSHOT' 8 | 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | maven { url "https://repository.mulesoft.org/nexus/content/repositories/public/" } 14 | 15 | } 16 | 17 | 18 | dependencies { 19 | //webclient-dependencies 20 | implementation 'org.springframework:spring-webflux:5.1.8.RELEASE' 21 | implementation 'io.projectreactor.netty:reactor-netty:0.8.9.RELEASE' 22 | 23 | //lombok 24 | compileOnly 'org.projectlombok:lombok:1.18.8' 25 | annotationProcessor 'org.projectlombok:lombok:1.18.8' 26 | implementation 'org.slf4j:slf4j-api:1.7.26' 27 | implementation 'org.slf4j:slf4j-simple:1.7.26' 28 | 29 | //jackson 30 | implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.9' 31 | implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9' 32 | implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.9' 33 | implementation 'com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.9' 34 | 35 | //junit4-dependencies 36 | testImplementation "junit:junit:4.12" 37 | 38 | //wiremock 39 | testImplementation "com.github.tomakehurst:wiremock-jre8-standalone:2.24.1" 40 | } 41 | 42 | -------------------------------------------------------------------------------- /movies-app-junit4/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dilipsundarraj1/wiremock-for-java-developers/3321de471628cb58641f5aa021503dd5ff791872/movies-app-junit4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /movies-app-junit4/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jul 29 08:53:08 CDT 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /movies-app-junit4/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /movies-app-junit4/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /movies-app-junit4/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'movies-app-junit4' 2 | 3 | -------------------------------------------------------------------------------- /movies-app-junit4/src/main/java/com/learnwiremock/constants/MoviesAppConstants.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.constants; 2 | 3 | import org.springframework.web.util.UriBuilder; 4 | 5 | import java.net.URI; 6 | import java.util.function.Function; 7 | 8 | public class MoviesAppConstants { 9 | 10 | public static final String GET_ALL_MOVIES_V1 = "/movieservice/v1/allMovies"; 11 | public static final String MOVIE_BY_ID_PATH_PARAM_V1 = "/movieservice/v1/movie/{id}"; 12 | public static final String MOVIE_BY_NAME_QUERY_PARAM_V1 = "/movieservice/v1/movieName"; 13 | public static final String MOVIE_BY_YEAR_QUERY_PARAM_V1 ="/movieservice/v1/movieYear"; 14 | public static final String ADD_MOVIE_V1 ="/movieservice/v1/movie"; 15 | } 16 | -------------------------------------------------------------------------------- /movies-app-junit4/src/main/java/com/learnwiremock/dto/Movie.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.time.LocalDate; 8 | 9 | @Data 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class Movie { 13 | 14 | public Long movie_id; 15 | public String name; 16 | public String cast; 17 | public Integer year; 18 | public LocalDate release_date; 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /movies-app-junit4/src/main/java/com/learnwiremock/exception/MovieErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.exception; 2 | 3 | import org.springframework.web.reactive.function.client.WebClientResponseException; 4 | 5 | public class MovieErrorResponse extends RuntimeException { 6 | public MovieErrorResponse(String statusText, WebClientResponseException ex) { 7 | super(statusText,ex); 8 | } 9 | 10 | public MovieErrorResponse(Exception ex) { 11 | super(ex); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /movies-app-junit4/src/main/java/com/learnwiremock/service/MoviesRestClient.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.learnwiremock.constants.MoviesAppConstants; 4 | import com.learnwiremock.dto.Movie; 5 | import com.learnwiremock.exception.MovieErrorResponse; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.web.reactive.function.client.WebClient; 8 | import org.springframework.web.reactive.function.client.WebClientResponseException; 9 | import org.springframework.web.util.UriComponentsBuilder; 10 | 11 | import java.util.List; 12 | 13 | import static com.learnwiremock.constants.MoviesAppConstants.MOVIE_BY_ID_PATH_PARAM_V1; 14 | 15 | 16 | @Slf4j 17 | public class MoviesRestClient { 18 | 19 | private WebClient webClient; 20 | 21 | public MoviesRestClient(WebClient webClient) { 22 | this.webClient = webClient; 23 | } 24 | 25 | public List retrieveAllMovies() { 26 | 27 | //http://localhost:8081/movieservice/v1/allMovies 28 | try { 29 | return webClient.get().uri(MoviesAppConstants.GET_ALL_MOVIES_V1) 30 | .retrieve() 31 | .bodyToFlux(Movie.class) 32 | .collectList() 33 | .block(); 34 | } catch (WebClientResponseException ex) { 35 | log.error("WebClientResponseException in retrieveAllMovies. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 36 | throw new MovieErrorResponse(ex.getStatusText(), ex); 37 | } catch (Exception ex) { 38 | log.error("Exception in retrieveAllMovies and the message is {} ", ex.getMessage() + ex); 39 | throw new MovieErrorResponse(ex); 40 | } 41 | } 42 | 43 | public Movie retrieveMovieById(Integer movieId) { 44 | 45 | //http://localhost:8081/movieservice/v1/movie/100 46 | try { 47 | return webClient.get().uri(MOVIE_BY_ID_PATH_PARAM_V1, movieId) 48 | .retrieve() 49 | .bodyToMono(Movie.class) 50 | .block(); 51 | } catch (WebClientResponseException ex) { 52 | log.error("WebClientResponseException in retrieveMovieById. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 53 | throw new MovieErrorResponse(ex.getStatusText(), ex); 54 | } catch (Exception ex) { 55 | log.error("Exception in retrieveMovieById and the message is {} ", ex); 56 | throw new MovieErrorResponse(ex); 57 | } 58 | } 59 | 60 | public List retrieveMoviebyName(String name) { 61 | 62 | // http://localhost:8081/movieservice/v1/movieName?movie_name=ABC 63 | 64 | String retrieveByNameUri = UriComponentsBuilder.fromUriString(MoviesAppConstants.MOVIE_BY_NAME_QUERY_PARAM_V1) 65 | .queryParam("movie_name", name) 66 | .buildAndExpand() 67 | .toUriString(); 68 | try { 69 | return webClient.get().uri(retrieveByNameUri) 70 | .retrieve() 71 | .bodyToFlux(Movie.class) 72 | .collectList() 73 | .block(); 74 | } catch (WebClientResponseException ex) { 75 | log.error("WebClientResponseException in retrieveMoviebyName. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 76 | throw new MovieErrorResponse(ex.getStatusText(), ex); 77 | } catch (Exception ex) { 78 | log.error("Exception in retrieveMoviebyName and the message is {} ", ex); 79 | throw new MovieErrorResponse(ex); 80 | } 81 | 82 | } 83 | 84 | public List retrieveMoviebyYear(Integer movieYear) { 85 | 86 | // http://localhost:8081/movieservice/v1/movieYear?year=1950 87 | 88 | String retrieveByNameUri = UriComponentsBuilder.fromUriString(MoviesAppConstants.MOVIE_BY_YEAR_QUERY_PARAM_V1) 89 | .queryParam("year", movieYear) 90 | .buildAndExpand() 91 | .toUriString(); 92 | try { 93 | return webClient.get().uri(retrieveByNameUri) 94 | .retrieve() 95 | .bodyToFlux(Movie.class) 96 | .collectList() 97 | .block(); 98 | } catch (WebClientResponseException ex) { 99 | log.error("WebClientResponseException in retrieveMoviebyYear. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 100 | throw new MovieErrorResponse(ex.getStatusText(), ex); 101 | } catch (Exception ex) { 102 | log.error("Exception in retrieveMoviebyYear and the message is {} ", ex); 103 | throw new MovieErrorResponse(ex); 104 | } 105 | 106 | } 107 | 108 | public Movie addMovie( Movie newMovie){ 109 | 110 | //http://localhost:8081/movieservice/v1/movie 111 | try { 112 | return webClient.post().uri(MoviesAppConstants.ADD_MOVIE_V1) 113 | .syncBody(newMovie) 114 | .retrieve() 115 | .bodyToMono(Movie.class) 116 | .block(); 117 | } catch (WebClientResponseException ex) { 118 | log.error("WebClientResponseException in addMovie. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 119 | throw new MovieErrorResponse(ex.getStatusText(), ex); 120 | } catch (Exception ex) { 121 | log.error("Exception in addMovie and the message is {} ", ex); 122 | throw new MovieErrorResponse(ex); 123 | } 124 | 125 | } 126 | 127 | 128 | public Movie updateMovie(Integer movieId, Movie movie){ 129 | try { 130 | return webClient.put().uri(MOVIE_BY_ID_PATH_PARAM_V1, movieId) 131 | .syncBody(movie) 132 | .retrieve() 133 | .bodyToMono(Movie.class) 134 | .block(); 135 | }catch (WebClientResponseException ex) { 136 | log.error("WebClientResponseException in updateMovie. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 137 | throw new MovieErrorResponse(ex.getStatusText(), ex); 138 | } catch (Exception ex) { 139 | log.error("Exception in updateMovie and the message is {} ", ex); 140 | throw new MovieErrorResponse(ex); 141 | } 142 | 143 | } 144 | 145 | public String deleteMovie(Integer movieId){ 146 | 147 | try{ 148 | return webClient.delete().uri(MOVIE_BY_ID_PATH_PARAM_V1, movieId) 149 | .retrieve() 150 | .bodyToMono(String.class) 151 | .block(); 152 | 153 | }catch (WebClientResponseException ex) { 154 | log.error("WebClientResponseException in deleteMovie. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 155 | throw new MovieErrorResponse(ex.getStatusText(), ex); 156 | } catch (Exception ex) { 157 | log.error("Exception in deleteMovie and the message is {} ", ex); 158 | throw new MovieErrorResponse(ex); 159 | } 160 | } 161 | 162 | public String deleteMovieByName(String movieName){ 163 | 164 | try{ 165 | String deleteMovieByNameURI = UriComponentsBuilder.fromUriString(MoviesAppConstants.MOVIE_BY_NAME_QUERY_PARAM_V1) 166 | .queryParam("movie_name", movieName) 167 | .buildAndExpand() 168 | .toUriString(); 169 | 170 | webClient.delete().uri(deleteMovieByNameURI) 171 | .retrieve() 172 | .bodyToMono(Void.class) 173 | .block(); 174 | 175 | }catch (WebClientResponseException ex) { 176 | log.error("WebClientResponseException in deleteMovie. Status code is {} and the message is {} ", ex.getRawStatusCode(), ex.getResponseBodyAsString()); 177 | throw new MovieErrorResponse(ex.getStatusText(), ex); 178 | } catch (Exception ex) { 179 | log.error("Exception in deleteMovie and the message is {} ", ex); 180 | throw new MovieErrorResponse(ex); 181 | } 182 | 183 | return "Movie Deleted Successfully"; 184 | } 185 | 186 | } 187 | -------------------------------------------------------------------------------- /movies-app-junit4/src/test/java/com/learnwiremock/service/MoviesRestClientServerFaultTest.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.github.tomakehurst.wiremock.WireMockServer; 4 | import com.github.tomakehurst.wiremock.client.WireMock; 5 | import com.github.tomakehurst.wiremock.common.ConsoleNotifier; 6 | import com.github.tomakehurst.wiremock.core.Options; 7 | import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; 8 | import com.github.tomakehurst.wiremock.http.Fault; 9 | import com.github.tomakehurst.wiremock.junit.WireMockRule; 10 | import com.learnwiremock.dto.Movie; 11 | import com.learnwiremock.exception.MovieErrorResponse; 12 | import io.netty.channel.Channel; 13 | import io.netty.channel.ChannelOption; 14 | import io.netty.handler.timeout.ReadTimeoutHandler; 15 | import io.netty.handler.timeout.WriteTimeoutHandler; 16 | import org.junit.Before; 17 | import org.junit.Rule; 18 | import org.junit.Test; 19 | import org.springframework.http.HttpStatus; 20 | import org.springframework.http.MediaType; 21 | import org.springframework.http.client.reactive.ReactorClientHttpConnector; 22 | import org.springframework.web.reactive.function.client.WebClient; 23 | import reactor.netty.http.client.HttpClient; 24 | import reactor.netty.tcp.TcpClient; 25 | 26 | import java.util.List; 27 | 28 | import static com.github.tomakehurst.wiremock.client.WireMock.*; 29 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; 30 | 31 | public class MoviesRestClientServerFaultTest { 32 | 33 | MoviesRestClient moviesRestClient; 34 | WebClient webClient; 35 | 36 | 37 | Options options = wireMockConfig(). 38 | port(8088) 39 | .notifier(new ConsoleNotifier(true)) 40 | .extensions(new ResponseTemplateTransformer(true)); 41 | 42 | TcpClient tcpClient = TcpClient.create() 43 | .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) 44 | .doOnConnected(connection -> { 45 | connection.addHandlerLast(new ReadTimeoutHandler(5)) 46 | .addHandlerLast(new WriteTimeoutHandler(5)); 47 | }); 48 | 49 | @Rule 50 | public WireMockRule wireMockRule = new WireMockRule(options); 51 | 52 | @Before 53 | public void setUp() { 54 | int port = wireMockRule.port(); 55 | String baseUrl = String.format("http://localhost:%s/", port); 56 | System.out.println("baseUrl : " + baseUrl); 57 | //webClient = WebClient.create(baseUrl); 58 | webClient = WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient))) 59 | .baseUrl(baseUrl).build(); 60 | moviesRestClient = new MoviesRestClient(webClient); 61 | } 62 | 63 | @Test(expected = MovieErrorResponse.class) 64 | public void retrieveAllMovies() { 65 | 66 | //given 67 | stubFor(get(anyUrl()) 68 | .willReturn(serverError())); 69 | 70 | //then 71 | moviesRestClient.retrieveAllMovies(); 72 | 73 | } 74 | 75 | @Test(expected = MovieErrorResponse.class) 76 | public void retrieveAllMovies_503_serviceUnAvailable() { 77 | 78 | //given 79 | stubFor(get(anyUrl()) 80 | .willReturn(serverError() 81 | .withStatus(HttpStatus.SERVICE_UNAVAILABLE.value()) 82 | .withBody("Service Unavailable"))); 83 | 84 | //then 85 | moviesRestClient.retrieveAllMovies(); 86 | 87 | 88 | } 89 | 90 | @Test(expected = MovieErrorResponse.class) 91 | public void retrieveAllMovies_FaultResponse() { 92 | 93 | //given 94 | stubFor(get(anyUrl()) 95 | .willReturn(aResponse().withFault(Fault.EMPTY_RESPONSE))); 96 | 97 | //then 98 | moviesRestClient.retrieveAllMovies(); 99 | 100 | } 101 | 102 | @Test(expected = MovieErrorResponse.class) 103 | public void retrieveAllMovies_RandomDataThenClose() { 104 | 105 | //given 106 | stubFor(get(anyUrl()) 107 | .willReturn(aResponse().withFault(Fault.RANDOM_DATA_THEN_CLOSE))); 108 | 109 | //then 110 | moviesRestClient.retrieveAllMovies(); 111 | 112 | } 113 | 114 | @Test(expected = MovieErrorResponse.class) 115 | public void retrieveAllMovies_fixedDelay() { 116 | 117 | //given 118 | stubFor(get(anyUrl()) 119 | .willReturn(ok().withFixedDelay(10000))); 120 | 121 | //then 122 | moviesRestClient.retrieveAllMovies(); 123 | 124 | } 125 | 126 | @Test(expected = MovieErrorResponse.class) 127 | public void retrieveAllMovies_RandomDelay() { 128 | 129 | //given 130 | stubFor(get(anyUrl()) 131 | .willReturn(ok().withUniformRandomDelay(6000,10000))); 132 | 133 | //then 134 | moviesRestClient.retrieveAllMovies(); 135 | 136 | } 137 | 138 | } 139 | 140 | -------------------------------------------------------------------------------- /movies-app-junit4/src/test/java/com/learnwiremock/service/MoviesRestClientTest.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.github.tomakehurst.wiremock.WireMockServer; 4 | import com.github.tomakehurst.wiremock.client.WireMock; 5 | import com.github.tomakehurst.wiremock.common.ConsoleNotifier; 6 | import com.github.tomakehurst.wiremock.core.Options; 7 | import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; 8 | import com.github.tomakehurst.wiremock.junit.WireMockRule; 9 | import com.learnwiremock.constants.MoviesAppConstants; 10 | import com.learnwiremock.dto.Movie; 11 | import com.learnwiremock.exception.MovieErrorResponse; 12 | import org.junit.Before; 13 | import org.junit.Rule; 14 | import org.junit.Test; 15 | import org.springframework.http.HttpHeaders; 16 | import org.springframework.http.HttpStatus; 17 | import org.springframework.http.MediaType; 18 | import org.springframework.web.reactive.function.client.WebClient; 19 | import org.springframework.web.reactive.function.client.WebClientResponseException; 20 | 21 | import java.time.LocalDate; 22 | import java.util.List; 23 | 24 | import static com.github.tomakehurst.wiremock.client.WireMock.*; 25 | import static com.github.tomakehurst.wiremock.client.WireMock.verify; 26 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; 27 | import static com.learnwiremock.constants.MoviesAppConstants.*; 28 | import static org.junit.Assert.assertEquals; 29 | import static org.junit.Assert.assertTrue; 30 | 31 | public class MoviesRestClientTest { 32 | 33 | MoviesRestClient moviesRestClient; 34 | WebClient webClient; 35 | 36 | 37 | 38 | Options options = wireMockConfig(). 39 | port(8088) 40 | .notifier(new ConsoleNotifier(true)) 41 | .extensions(new ResponseTemplateTransformer(true)); 42 | 43 | @Rule 44 | public WireMockRule wireMockRule = new WireMockRule(options); 45 | 46 | @Before 47 | public void setUp() { 48 | int port = wireMockRule.port(); 49 | String baseUrl = String.format("http://localhost:%s/", port); 50 | System.out.println("baseUrl : " + baseUrl); 51 | webClient = WebClient.create(baseUrl); 52 | moviesRestClient = new MoviesRestClient(webClient); 53 | 54 | stubFor(any(anyUrl()).willReturn(aResponse().proxiedFrom("http://localhost:8081"))); 55 | } 56 | 57 | @Test 58 | public void retrieveAllMovies() { 59 | 60 | //given 61 | stubFor(get(anyUrl()) 62 | .willReturn(WireMock.aResponse() 63 | .withStatus(HttpStatus.OK.value()) 64 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 65 | .withBodyFile("all-movies.json"))); 66 | 67 | //when 68 | List movieList = moviesRestClient.retrieveAllMovies(); 69 | System.out.println("movieList : " + movieList); 70 | 71 | //then 72 | assertTrue(movieList.size() > 0); 73 | } 74 | 75 | @Test 76 | public void retrieveAllMovies_matchesUrl() { 77 | 78 | //given 79 | stubFor(get(urlPathEqualTo(MoviesAppConstants.GET_ALL_MOVIES_V1)) 80 | .willReturn(WireMock.aResponse() 81 | .withStatus(HttpStatus.OK.value()) 82 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 83 | .withBodyFile("all-movies.json"))); 84 | 85 | //when 86 | List movieList = moviesRestClient.retrieveAllMovies(); 87 | System.out.println("movieList : " + movieList); 88 | 89 | //then 90 | assertTrue(movieList.size() > 0); 91 | } 92 | 93 | 94 | @Test 95 | public void retrieveMovieById() { 96 | //given 97 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]")) 98 | .willReturn(WireMock.aResponse() 99 | .withStatus(HttpStatus.OK.value()) 100 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 101 | .withBodyFile("movie.json"))); 102 | Integer movieId = 9; 103 | 104 | //when 105 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 106 | 107 | //then 108 | assertEquals("Batman Begins", movie.getName()); 109 | 110 | } 111 | 112 | @Test 113 | public void retrieveMovieById_reponseTemplating() { 114 | //given 115 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]")) 116 | .willReturn(WireMock.aResponse() 117 | .withStatus(HttpStatus.OK.value()) 118 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 119 | .withBodyFile("movie-template.json"))); 120 | Integer movieId = 8; 121 | 122 | //when 123 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 124 | System.out.println("movie : " + movie); 125 | 126 | //then 127 | assertEquals("Batman Begins", movie.getName()); 128 | assertEquals(8, movie.getMovie_id().intValue()); 129 | 130 | } 131 | 132 | 133 | @Test(expected = MovieErrorResponse.class) 134 | public void retrieveMovieById_notFound() { 135 | //given 136 | stubFor(get(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 137 | .willReturn(WireMock.aResponse() 138 | .withStatus(HttpStatus.NOT_FOUND.value()) 139 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 140 | .withBodyFile("404-movieId.json"))); 141 | Integer movieId = 100; 142 | 143 | //when 144 | moviesRestClient.retrieveMovieById(movieId); 145 | 146 | } 147 | 148 | @Test 149 | public void retrieveMoviebyName() { 150 | 151 | //given 152 | String movieName = "Avengers"; 153 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name="+movieName)) 154 | .willReturn(WireMock.aResponse() 155 | .withStatus(HttpStatus.OK.value()) 156 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 157 | .withBodyFile("avengers.json"))); 158 | 159 | 160 | //when 161 | List movieList = moviesRestClient.retrieveMoviebyName(movieName); 162 | 163 | //then 164 | String castExpected = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 165 | assertEquals(4, movieList.size()); 166 | assertEquals(castExpected, movieList.get(0).getCast()); 167 | 168 | } 169 | 170 | @Test 171 | public void retrieveMoviebyName_responeTemplating() { 172 | 173 | //given 174 | String movieName = "Avengers"; 175 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name="+movieName)) 176 | .willReturn(WireMock.aResponse() 177 | .withStatus(HttpStatus.OK.value()) 178 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 179 | .withBodyFile("movie-byName-template.json"))); 180 | 181 | 182 | //when 183 | List movieList = moviesRestClient.retrieveMoviebyName(movieName); 184 | 185 | //then 186 | String castExpected = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 187 | assertEquals(4, movieList.size()); 188 | assertEquals(castExpected, movieList.get(0).getCast()); 189 | 190 | } 191 | 192 | 193 | @Test 194 | public void retrieveMoviebyName_approach2() { 195 | 196 | //given 197 | String movieName = "Avengers"; 198 | stubFor(get(urlPathEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1)) 199 | // .withQueryParam("movie_name", equalTo(movieName) ) 200 | .willReturn(WireMock.aResponse() 201 | .withStatus(HttpStatus.OK.value()) 202 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 203 | .withBodyFile("avengers.json"))); 204 | 205 | 206 | //when 207 | List movieList = moviesRestClient.retrieveMoviebyName(movieName); 208 | 209 | //then 210 | String castExpected = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 211 | assertEquals(4, movieList.size()); 212 | assertEquals(castExpected, movieList.get(0).getCast()); 213 | 214 | } 215 | 216 | @Test(expected = MovieErrorResponse.class) 217 | public void retrieveMoviebyName_Not_Found() { 218 | 219 | //given 220 | String movieName = "ABC"; 221 | stubFor(get(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name="+movieName)) 222 | .willReturn(WireMock.aResponse() 223 | .withStatus(HttpStatus.NOT_FOUND.value()) 224 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 225 | .withBodyFile("404-movieName.json"))); 226 | 227 | 228 | //when 229 | moviesRestClient.retrieveMoviebyName(movieName); 230 | 231 | } 232 | 233 | @Test 234 | public void retrieveMoviebyYear() { 235 | //given 236 | Integer year = 2012; 237 | stubFor(get(urlEqualTo(MOVIE_BY_YEAR_QUERY_PARAM_V1+"?year="+year)) 238 | .willReturn(WireMock.aResponse() 239 | .withStatus(HttpStatus.OK.value()) 240 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 241 | .withBodyFile("year-template.json"))); 242 | 243 | //when 244 | List movieList = moviesRestClient.retrieveMoviebyYear(year); 245 | 246 | //then 247 | assertEquals(2, movieList.size()); 248 | 249 | } 250 | 251 | @Test(expected = MovieErrorResponse.class) 252 | public void retrieveMoviebyYear_not_found() { 253 | //given 254 | Integer year = 1950; 255 | stubFor(get(urlEqualTo(MOVIE_BY_YEAR_QUERY_PARAM_V1+"?year="+year)) 256 | .withQueryParam("year", equalTo(year.toString())) 257 | .willReturn(WireMock.aResponse() 258 | .withStatus(HttpStatus.NOT_FOUND.value()) 259 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 260 | .withBodyFile("404-movieyear.json"))); 261 | 262 | //when 263 | moviesRestClient.retrieveMoviebyYear(year); 264 | 265 | } 266 | 267 | @Test 268 | public void addMovie() { 269 | //given 270 | Movie movie = new Movie(null, "Toys Story 4", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 271 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 272 | // .withQueryParam("movie_name", equalTo(movieName) ) 273 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 4"))) 274 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 275 | .willReturn(WireMock.aResponse() 276 | .withStatus(HttpStatus.OK.value()) 277 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 278 | .withBodyFile("add-movie.json"))); 279 | 280 | //when 281 | Movie addedMovie = moviesRestClient.addMovie(movie); 282 | System.out.println(addedMovie); 283 | 284 | //then 285 | assertTrue(addedMovie.getMovie_id() != null); 286 | } 287 | 288 | @Test 289 | public void addMovie_responseTemplating() { 290 | //given 291 | Movie movie = new Movie(null, "Toys Story 4", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 292 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 293 | // .withQueryParam("movie_name", equalTo(movieName) ) 294 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 4"))) 295 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 296 | .willReturn(WireMock.aResponse() 297 | .withStatus(HttpStatus.OK.value()) 298 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 299 | .withBodyFile("add-movie-template.json"))); 300 | 301 | //when 302 | Movie addedMovie = moviesRestClient.addMovie(movie); 303 | System.out.println(addedMovie); 304 | 305 | //then 306 | assertTrue(addedMovie.getMovie_id() != null); 307 | } 308 | 309 | @Test(expected = MovieErrorResponse.class) 310 | public void addMovie_badRequest() { 311 | //given 312 | Movie movie = new Movie(null, null, "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 313 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 314 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 315 | .willReturn(WireMock.aResponse() 316 | .withStatus(HttpStatus.BAD_REQUEST.value()) 317 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 318 | .withBodyFile("400-invalid-input.json"))); 319 | 320 | //when 321 | String expectedErrorMessage = "Please pass all the input fields : [name]"; 322 | moviesRestClient.addMovie(movie); 323 | } 324 | 325 | @Test 326 | public void updateMovie() { 327 | //given 328 | Integer movieId = 3; 329 | String cast = "ABC"; 330 | Movie movie = new Movie(null, null, cast, null, null); 331 | stubFor(put(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 332 | .withRequestBody(matchingJsonPath(("$.cast"), containing(cast))) 333 | .willReturn(WireMock.aResponse() 334 | .withStatus(HttpStatus.OK.value()) 335 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 336 | .withBodyFile("updatemovie-template.json"))); 337 | 338 | //when 339 | Movie updatedMovie = moviesRestClient.updateMovie(movieId, movie); 340 | 341 | //then 342 | assertTrue(updatedMovie.getCast().contains(cast)); 343 | } 344 | 345 | @Test(expected = MovieErrorResponse.class) 346 | public void updateMovie_notFound() { 347 | //given 348 | Integer movieId = 100; 349 | String cast = "ABC"; 350 | Movie movie = new Movie(null, null, cast, null, null); 351 | stubFor(put(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 352 | .withRequestBody(matchingJsonPath(("$.cast"), containing(cast))) 353 | .willReturn(WireMock.aResponse() 354 | .withStatus(HttpStatus.NOT_FOUND.value()) 355 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 356 | 357 | 358 | //then 359 | moviesRestClient.updateMovie(movieId, movie); 360 | } 361 | 362 | @Test 363 | public void deleteMovie() { 364 | //given 365 | Movie movie = new Movie(null, "Toys Story 5", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 366 | 367 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 368 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 5"))) 369 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 370 | .willReturn(WireMock.aResponse() 371 | .withStatus(HttpStatus.OK.value()) 372 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 373 | .withBodyFile("add-movie-template.json"))); 374 | Movie addedMovie = moviesRestClient.addMovie(movie); 375 | 376 | String expectedErrorMessage = "Movie Deleted Successfully"; 377 | stubFor(delete(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 378 | .willReturn(WireMock.aResponse() 379 | .withStatus(HttpStatus.OK.value()) 380 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 381 | .withBody(expectedErrorMessage))); 382 | 383 | //when 384 | String responseMessage = moviesRestClient.deleteMovie(addedMovie.getMovie_id().intValue()); 385 | 386 | //then 387 | assertEquals(expectedErrorMessage, responseMessage); 388 | } 389 | 390 | @Test(expected = MovieErrorResponse.class) 391 | public void deleteMovie_NotFound() { 392 | //given 393 | Integer id = 100; 394 | stubFor(delete(urlPathMatching("/movieservice/v1/movie/[0-9]+")) 395 | .willReturn(WireMock.aResponse() 396 | .withStatus(HttpStatus.NOT_FOUND.value()) 397 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 398 | 399 | //then 400 | moviesRestClient.deleteMovie(id); 401 | 402 | } 403 | 404 | 405 | @Test 406 | public void deleteMovieByName() { 407 | //given 408 | Movie movie = new Movie(null, "Toys Story 5", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 409 | 410 | stubFor(post(urlPathEqualTo(ADD_MOVIE_V1)) 411 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 5"))) 412 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom"))) 413 | .willReturn(WireMock.aResponse() 414 | .withStatus(HttpStatus.OK.value()) 415 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 416 | .withBodyFile("add-movie-template.json"))); 417 | Movie addedMovie = moviesRestClient.addMovie(movie); 418 | 419 | String expectedErrorMessage = "Movie Deleted Successfully"; 420 | stubFor(delete(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name=Toys%20Story%205")) 421 | .willReturn(WireMock.aResponse() 422 | .withStatus(HttpStatus.OK.value()) 423 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 424 | 425 | //when 426 | String responseMessage = moviesRestClient.deleteMovieByName(addedMovie.getName()); 427 | 428 | //then 429 | assertEquals(expectedErrorMessage, responseMessage); 430 | 431 | verify(exactly(1),postRequestedFor(urlPathEqualTo(ADD_MOVIE_V1)) 432 | .withRequestBody(matchingJsonPath(("$.name"),equalTo("Toys Story 5"))) 433 | .withRequestBody(matchingJsonPath(("$.cast"), containing("Tom")))); 434 | 435 | verify(exactly(1),deleteRequestedFor(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name=Toys%20Story%205"))); 436 | 437 | } 438 | 439 | @Test 440 | public void deleteMovieByName_selectiveproxying() { 441 | //given 442 | Movie movie = new Movie(null, "Toys Story 5", "Tom Hanks, Tim Allen", 2019, LocalDate.of(2019, 06, 20)); 443 | Movie addedMovie = moviesRestClient.addMovie(movie); 444 | 445 | String expectedErrorMessage = "Movie Deleted Successfully"; 446 | stubFor(delete(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name=Toys%20Story%205")) 447 | .willReturn(WireMock.aResponse() 448 | .withStatus(HttpStatus.OK.value()) 449 | .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))); 450 | 451 | //when 452 | String responseMessage = moviesRestClient.deleteMovieByName(addedMovie.getName()); 453 | 454 | //then 455 | assertEquals(expectedErrorMessage, responseMessage); 456 | 457 | verify(exactly(1),deleteRequestedFor(urlEqualTo(MOVIE_BY_NAME_QUERY_PARAM_V1+"?movie_name=Toys%20Story%205"))); 458 | 459 | } 460 | } 461 | 462 | -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/400-invalid-input.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 400, 4 | "error": "Bad Request", 5 | "message": "Please pass all the input fields : [name]", 6 | "path": "{{request.path}}" 7 | } 8 | -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/404-movieId.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given Id - {{request.path.[3]}}", 6 | "path": "{{request.path}}" 7 | } 8 | -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/404-moviename.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given name - {{request.query.movie_name}}", 6 | "path": "{{request.path}}" 7 | } -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/404-movieyear.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "{{now}}", 3 | "status": 404, 4 | "error": "Not Found", 5 | "message": "No Movie Available with the given year - {{request.query.year}}", 6 | "path": "{{request.path}}" 7 | } -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/add-movie-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": "{{randomValue length=2 type='NUMERIC'}}", 3 | "name": "{{jsonPath request.body '$.name'}}", 4 | "year": "{{jsonPath request.body '$.year'}}", 5 | "cast": "{{jsonPath request.body '$.cast'}}", 6 | "release_date": "{{date parseDate(jsonPath request.body '$.release_date')}}" 7 | } -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/add-movie.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": 11, 3 | "name": "Toys Story 4", 4 | "year": 2019, 5 | "cast": "Tom Hanks, Tim Allen", 6 | "release_date": "2019-06-20" 7 | } -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/all-movies.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "movie_id": 1, 4 | "name": "Batman Begins", 5 | "year": 2005, 6 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 7 | "release_date": "2005-06-15" 8 | }, 9 | { 10 | "movie_id": 2, 11 | "name": "Dark Knight", 12 | "year": 2008, 13 | "cast": "Christian Bale, Heath Ledger , Michael Caine", 14 | "release_date": "2008-07-18" 15 | }, 16 | { 17 | "movie_id": 3, 18 | "name": "The Dark Knight Rises", 19 | "year": 2012, 20 | "cast": "Christian Bale, Heath Ledger , Michael Caine", 21 | "release_date": "2012-07-20" 22 | }, 23 | { 24 | "movie_id": 4, 25 | "name": "The Avengers", 26 | "year": 2012, 27 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 28 | "release_date": "2012-05-04" 29 | }, 30 | { 31 | "movie_id": 5, 32 | "name": "Avengers: Age of Ultron", 33 | "year": 2015, 34 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 35 | "release_date": "2015-05-01" 36 | }, 37 | { 38 | "movie_id": 6, 39 | "name": "Avengers: Infinity War", 40 | "year": 2018, 41 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 42 | "release_date": "2018-04-27" 43 | }, 44 | { 45 | "movie_id": 7, 46 | "name": "Avengers: End Game", 47 | "year": 2019, 48 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 49 | "release_date": "2019-04-26" 50 | }, 51 | { 52 | "movie_id": 8, 53 | "name": "The Hangover", 54 | "year": 2009, 55 | "cast": "Bradley Cooper, Ed Helms , Zach Galifianakis", 56 | "release_date": "2009-06-05" 57 | }, 58 | { 59 | "movie_id": 9, 60 | "name": "The Imitation Game", 61 | "year": 2014, 62 | "cast": "Benedict Cumberbatch, Keira Knightley", 63 | "release_date": "2014-12-25" 64 | }, 65 | { 66 | "movie_id": 10, 67 | "name": "The Departed", 68 | "year": 2006, 69 | "cast": "Leonardo DiCaprio, Matt Damon , Mark Wahlberg", 70 | "release_date": "2006-10-06" 71 | } 72 | ] -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/avengers.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "movie_id": 4, 3 | "name": "The Avengers", 4 | "year": 2012, 5 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 6 | "release_date": "2012-05-04" 7 | }, 8 | { 9 | "movie_id": 5, 10 | "name": "Avengers: Age of Ultron", 11 | "year": 2015, 12 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 13 | "release_date": "2015-05-01" 14 | }, 15 | { 16 | "movie_id": 6, 17 | "name": "Avengers: Infinity War", 18 | "year": 2018, 19 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 20 | "release_date": "2018-04-27" 21 | }, 22 | { 23 | "movie_id": 7, 24 | "name": "Avengers: End Game", 25 | "year": 2019, 26 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 27 | "release_date": "2019-04-26" 28 | }] -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/movie-byname-template.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "movie_id": 4, 3 | "name": "The {{request.query.movie_name}}", 4 | "year": 2012, 5 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 6 | "release_date": "2012-05-04" 7 | }, 8 | { 9 | "movie_id": 5, 10 | "name": "{{request.query.movie_name}}: Age of Ultron", 11 | "year": 2015, 12 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 13 | "release_date": "2015-05-01" 14 | }, 15 | { 16 | "movie_id": 6, 17 | "name": "{{request.query.movie_name}}: Infinity War", 18 | "year": 2018, 19 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 20 | "release_date": "2018-04-27" 21 | }, 22 | { 23 | "movie_id": 7, 24 | "name": "{{request.query.movie_name}}: End Game", 25 | "year": 2019, 26 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 27 | "release_date": "2019-04-26" 28 | }] -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/movie-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": "{{request.path.[3]}}", 3 | "name": "Batman Begins", 4 | "year": 2005, 5 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 6 | "release_date": "2005-06-15" 7 | } -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/movie.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": 1, 3 | "name": "Batman Begins", 4 | "year": 2005, 5 | "cast": "Christian Bale, Katie Holmes , Liam Neeson", 6 | "release_date": "2005-06-15" 7 | } -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/updatemovie-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "movie_id": "{{request.path.[3]}}", 3 | "name": "Toys Story 4", 4 | "year": 2019, 5 | "cast": "Tom Hanks, Tim Allen, {{jsonPath request.body '$.cast'}}", 6 | "release_date": "2019-06-20" 7 | } -------------------------------------------------------------------------------- /movies-app-junit4/src/test/resources/__files/year-template.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "movie_id": 3, 4 | "name": "The Dark Knight Rises", 5 | "year": "{{request.query.year}}", 6 | "cast": "Christian Bale, Heath Ledger , Michael Caine", 7 | "release_date": "2012-07-20" 8 | }, 9 | { 10 | "movie_id": 4, 11 | "name": "The Avengers", 12 | "year": "{{request.query.year}}", 13 | "cast": "Robert Downey Jr, Chris Evans , Chris HemsWorth", 14 | "release_date": "2012-05-04" 15 | } 16 | ] -------------------------------------------------------------------------------- /movies-app/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /movies-app/README.md: -------------------------------------------------------------------------------- 1 | # MovieApp 2 | 3 | - This is a application which connects to the Movies RESTFUL Service. 4 | 5 | ## How to enable JUnit5? 6 | 7 | - Please make the below changes to enable JUnit5 in your project. 8 | 9 | ### build.gradle 10 | 11 | - Add the below code to enable Junit5 as a test platform. 12 | 13 | ```youtrack 14 | test { 15 | useJUnitPlatform() // enables Junit5 16 | } 17 | ``` 18 | - Add this dependency to use the Junit% 19 | 20 | ```youtrack 21 | dependencies { 22 | //junit5-dependencies 23 | testImplementation('org.junit.jupiter:junit-jupiter:5.5.1') 24 | } 25 | ``` -------------------------------------------------------------------------------- /movies-app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | apply plugin: 'java' 5 | 6 | group 'com.learnwiremock' 7 | version '1.0-SNAPSHOT' 8 | 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | test{ 16 | useJUnitPlatform() 17 | } 18 | 19 | dependencies { 20 | //webclient-dependencies 21 | implementation 'org.springframework:spring-webflux:5.1.8.RELEASE' 22 | implementation 'io.projectreactor.netty:reactor-netty:0.8.9.RELEASE' 23 | 24 | //lombok 25 | compileOnly 'org.projectlombok:lombok:1.18.8' 26 | annotationProcessor 'org.projectlombok:lombok:1.18.8' 27 | implementation 'org.slf4j:slf4j-api:1.7.26' 28 | implementation 'org.slf4j:slf4j-simple:1.7.26' 29 | 30 | //jackson 31 | implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.9' 32 | implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9' 33 | implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.9' 34 | implementation 'com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.9' 35 | 36 | //junit5-dependencies 37 | testImplementation("org.junit.jupiter:junit-jupiter-engine:5.5.1") 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /movies-app/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dilipsundarraj1/wiremock-for-java-developers/3321de471628cb58641f5aa021503dd5ff791872/movies-app/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /movies-app/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jul 29 08:53:08 CDT 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /movies-app/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /movies-app/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /movies-app/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'movies-app' 2 | 3 | -------------------------------------------------------------------------------- /movies-app/src/main/java/com/learnwiremock/constants/MovieAppConstants.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.constants; 2 | 3 | public class MovieAppConstants { 4 | 5 | public final static String GET_ALL_MOVIES_V1 = "/movieservice/v1/allMovies"; 6 | public static final String MOVIE_BY_ID_PATH_PARAM_V1 = "/movieservice/v1/movie/{id}"; 7 | public static final String MOVIE_BY_NAME_QUERY_PARAM_V1 = "/movieservice/v1/movieName"; 8 | public static final String MOVIE_BY_YEAR_QUERY_PARAM_V1 = "/movieservice/v1/movieYear"; 9 | public static final String ADD_MOVIE_V1 = "/movieservice/v1/movie"; 10 | } 11 | -------------------------------------------------------------------------------- /movies-app/src/main/java/com/learnwiremock/dto/Movie.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.dto; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.time.LocalDate; 10 | 11 | @Data 12 | @Builder 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class Movie { 16 | 17 | private Long movie_id; 18 | 19 | private String name; 20 | 21 | private Integer year; 22 | 23 | private String cast; 24 | 25 | private LocalDate release_date; 26 | } 27 | -------------------------------------------------------------------------------- /movies-app/src/main/java/com/learnwiremock/exception/MovieErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.exception; 2 | 3 | public class MovieErrorResponse extends RuntimeException { 4 | 5 | public MovieErrorResponse(String message, Throwable cause) { 6 | super(message, cause); 7 | } 8 | public MovieErrorResponse(Throwable cause) { 9 | super(cause); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /movies-app/src/main/java/com/learnwiremock/service/MoviesRestClient.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.learnwiremock.dto.Movie; 4 | import com.learnwiremock.exception.MovieErrorResponse; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.web.reactive.function.client.WebClient; 7 | import org.springframework.web.reactive.function.client.WebClientResponseException; 8 | import org.springframework.web.util.UriComponentsBuilder; 9 | 10 | import java.net.URI; 11 | import java.util.List; 12 | 13 | import static com.learnwiremock.constants.MovieAppConstants.*; 14 | 15 | @Slf4j 16 | public class MoviesRestClient { 17 | 18 | private WebClient webClient; 19 | 20 | public MoviesRestClient(WebClient _webClient) { 21 | this.webClient = _webClient; 22 | } 23 | 24 | /** 25 | * Retrieve all the movies from the service. 26 | * 27 | * @return 28 | */ 29 | public List retrieveAllMovies() { 30 | String getAllMoviesUrl = GET_ALL_MOVIES_V1; 31 | List movieList; 32 | try { 33 | movieList = webClient.get().uri(getAllMoviesUrl) 34 | .retrieve() // actual call is made to the api 35 | .bodyToFlux(Movie.class) //body is converted to flux(Represents multiple items) 36 | .collectList() // collecting the httpResponse as a list\ 37 | .block(); // This call makes the Webclient to behave as a synchronous client. 38 | } catch (WebClientResponseException ex) { 39 | log.error("WebClientResponseException - Error Message is : {} ", ex, ex.getResponseBodyAsString()); 40 | throw new MovieErrorResponse(ex.getStatusText(), ex); 41 | } catch (Exception ex) { 42 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 43 | throw new MovieErrorResponse(ex); 44 | } 45 | return movieList; 46 | } 47 | 48 | public Movie retrieveMovieById(Integer movieId) { 49 | String movieByIdURL = MOVIE_BY_ID_PATH_PARAM_V1; 50 | Movie movie; 51 | try { 52 | movie = webClient.get().uri(movieByIdURL, movieId) //mapping the movie id to the url 53 | .retrieve() 54 | .bodyToMono(Movie.class) //body is converted to Mono(Represents single item) 55 | .block(); 56 | } catch (WebClientResponseException ex) { 57 | log.error("WebClientResponseException - Error Message is : {} ", ex, ex.getResponseBodyAsString()); 58 | throw new MovieErrorResponse(ex.getStatusText(), ex); 59 | } catch (Exception ex) { 60 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 61 | throw new MovieErrorResponse(ex); 62 | } 63 | return movie; 64 | } 65 | 66 | 67 | public List retrieveMovieByName(String movieName) { 68 | 69 | List movieList = null; 70 | String retrieveByNameUri = UriComponentsBuilder.fromUriString( MOVIE_BY_NAME_QUERY_PARAM_V1) 71 | .queryParam("movie_name", movieName) 72 | .buildAndExpand() 73 | .toUriString(); 74 | 75 | try { 76 | movieList = webClient.get().uri(retrieveByNameUri) 77 | .retrieve() 78 | .bodyToFlux(Movie.class) 79 | .collectList() 80 | .block(); 81 | } catch (WebClientResponseException ex) { 82 | log.error("WebClientResponseException in retrieveMovieByName - Error Message is : {} ", ex, ex.getResponseBodyAsString()); 83 | throw new MovieErrorResponse(ex.getStatusText(), ex); 84 | } catch (Exception ex) { 85 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 86 | throw new MovieErrorResponse(ex); 87 | } 88 | return movieList; 89 | } 90 | 91 | 92 | /** 93 | * This method makes a REST call to the Movies RESTFUL Service and retrieves a list of Movies as a response based on the year. 94 | * 95 | * @param year - Integer (Example : 2012,2013 etc.,) 96 | * @return - List 97 | */ 98 | public List retreieveMovieByYear(Integer year) { 99 | String retrieveByYearUri = UriComponentsBuilder.fromUriString( MOVIE_BY_YEAR_QUERY_PARAM_V1) 100 | .queryParam("year", year) 101 | .buildAndExpand() 102 | .toUriString(); 103 | List movieList; 104 | 105 | try { 106 | movieList = webClient.get().uri(retrieveByYearUri) 107 | .retrieve() 108 | .bodyToFlux(Movie.class) 109 | .collectList() 110 | .block(); 111 | } catch (WebClientResponseException ex) { 112 | log.error("WebClientResponseException in retreieveMovieByYear - Error Message is : {} ", ex, ex.getResponseBodyAsString()); 113 | throw new MovieErrorResponse(ex.getStatusText(), ex); 114 | } catch (Exception ex) { 115 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 116 | throw new MovieErrorResponse(ex); 117 | } 118 | return movieList; 119 | } 120 | 121 | /** 122 | * This method makes the REST call to add a new Movie to the Movies RESTFUL Service. 123 | * 124 | * @param newMovie 125 | * @return 126 | */ 127 | public Movie addNewMovie(Movie newMovie) { 128 | Movie movie; 129 | 130 | try { 131 | movie = webClient.post().uri( ADD_MOVIE_V1) 132 | .syncBody(newMovie) 133 | .retrieve() 134 | .bodyToMono(Movie.class) 135 | .block(); 136 | log.info("New Movie SuccessFully addded {} ", movie); 137 | } catch (WebClientResponseException ex) { 138 | log.error("WebClientResponseException - Error Message is : {} , and the Error Response Body is {}", ex, ex.getResponseBodyAsString()); 139 | throw new MovieErrorResponse(ex.getStatusText(), ex); 140 | } catch (Exception ex) { 141 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 142 | throw new MovieErrorResponse(ex); 143 | } 144 | return movie; 145 | } 146 | 147 | public Movie updateMovie(Integer movieId, Movie movie) { 148 | Movie updatedMovie; 149 | 150 | try { 151 | updatedMovie = webClient.put().uri( MOVIE_BY_ID_PATH_PARAM_V1, movieId) 152 | .syncBody(movie) 153 | .retrieve() 154 | .bodyToMono(Movie.class) 155 | .block(); 156 | log.info(" Movie SuccessFully updated {} ", updatedMovie); 157 | } catch (WebClientResponseException ex) { 158 | log.error("WebClientResponseException - Error Message is : {}", ex, ex.getResponseBodyAsString()); 159 | throw new MovieErrorResponse(ex.getStatusText(), ex); 160 | } catch (Exception ex) { 161 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 162 | throw new MovieErrorResponse(ex); 163 | } 164 | 165 | return updatedMovie; 166 | } 167 | 168 | public String deleteMovieById(Integer movieId) { 169 | 170 | String response; 171 | try { 172 | response = webClient.delete().uri( MOVIE_BY_ID_PATH_PARAM_V1, movieId) 173 | .retrieve() 174 | .bodyToMono(String.class) 175 | .block(); 176 | }catch (WebClientResponseException ex) { 177 | log.error("WebClientResponseException - Error Message is : {}", ex, ex.getResponseBodyAsString()); 178 | throw new MovieErrorResponse(ex.getStatusText(), ex); 179 | } catch (Exception ex) { 180 | log.error("Exception - The Error Message is {} ", ex.getMessage()); 181 | throw new MovieErrorResponse(ex); 182 | } 183 | 184 | return response; 185 | 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /movies-app/src/test/java/com/learnwiremock/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dilipsundarraj1/wiremock-for-java-developers/3321de471628cb58641f5aa021503dd5ff791872/movies-app/src/test/java/com/learnwiremock/.DS_Store -------------------------------------------------------------------------------- /movies-app/src/test/java/com/learnwiremock/helper/TestHelper.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.helper; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Paths; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.Stream; 8 | 9 | public class TestHelper { 10 | 11 | private static String filePath = "src/test/resources/data/"; 12 | 13 | public static String readFromPath(String fileName){ 14 | String data=null; 15 | try (Stream stream = Files.lines(Paths.get(filePath+fileName))) { 16 | data = stream 17 | .map((line) -> line.trim()) 18 | .collect(Collectors.joining()); 19 | } catch (IOException e) { 20 | e.printStackTrace(); 21 | } 22 | return data; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /movies-app/src/test/java/com/learnwiremock/service/MoviesRestClientTest.java: -------------------------------------------------------------------------------- 1 | package com.learnwiremock.service; 2 | 3 | import com.learnwiremock.dto.Movie; 4 | import com.learnwiremock.exception.MovieErrorResponse; 5 | import com.learnwiremock.helper.TestHelper; 6 | import org.junit.jupiter.api.*; 7 | import org.springframework.http.HttpHeaders; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.web.reactive.function.client.WebClient; 10 | 11 | import java.time.LocalDate; 12 | import java.util.List; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | import static org.junit.jupiter.api.Assertions.assertTrue; 16 | 17 | public class MoviesRestClientTest { 18 | 19 | MoviesRestClient moviesRestClient = null; 20 | WebClient webClient = null; 21 | 22 | @BeforeEach 23 | void setUp() { 24 | int port = 8081; 25 | final String baseUrl = String.format("http://localhost:%s/", port); 26 | webClient = WebClient.create(baseUrl); 27 | moviesRestClient = new MoviesRestClient(webClient); 28 | 29 | } 30 | 31 | @Test 32 | void getAllMovies() { 33 | //when 34 | List movieList = moviesRestClient.retrieveAllMovies(); 35 | System.out.println("movieList : " + movieList); 36 | 37 | //then 38 | assertTrue(!movieList.isEmpty()); 39 | } 40 | 41 | @Test 42 | void retrieveMovieById() { 43 | //given 44 | Integer movieId = 1; 45 | 46 | //when 47 | Movie movie = moviesRestClient.retrieveMovieById(movieId); 48 | 49 | //then 50 | assertEquals("Batman Begins", movie.getName()); 51 | } 52 | 53 | @Test 54 | void retrieveMovieById_NotFound() { 55 | //given 56 | Integer movieId = 100; 57 | 58 | //when 59 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.retrieveMovieById(movieId)); 60 | 61 | } 62 | 63 | @Test 64 | void retrieveMovieByName() { 65 | //given 66 | String movieName = "Avengers"; 67 | 68 | //when 69 | List movieList = moviesRestClient.retrieveMovieByName(movieName); 70 | 71 | //then 72 | String expectedCastName = "Robert Downey Jr, Chris Evans , Chris HemsWorth"; 73 | assertEquals(4, movieList.size()); 74 | assertEquals(expectedCastName, movieList.get(0).getCast()); 75 | } 76 | 77 | @Test 78 | void retrieveMovieByName_Not_Found() { 79 | //given 80 | String movieName = "ABC"; 81 | 82 | //whenretrieveMovieByYear 83 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.retrieveMovieByName(movieName)); 84 | } 85 | 86 | 87 | @Test 88 | void retrieveMovieByYear() { 89 | //given 90 | Integer year = 2012; 91 | 92 | //when 93 | List movieList = moviesRestClient.retreieveMovieByYear(year); 94 | 95 | //then 96 | assertEquals(2, movieList.size()); 97 | 98 | } 99 | 100 | @Test 101 | void retrieveMovieByYear_Not_Found() { 102 | //given 103 | Integer year = 1950; 104 | 105 | //when 106 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.retreieveMovieByYear(year)); 107 | 108 | } 109 | 110 | @Test 111 | void addNewMovie() { 112 | //given 113 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 114 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 115 | 116 | //when 117 | Movie movie = moviesRestClient.addNewMovie(toyStory); 118 | 119 | //then 120 | assertTrue(movie.getMovie_id() != null); 121 | 122 | } 123 | 124 | @Test 125 | @DisplayName("Passing the Movie name and year as Null") 126 | void addNewMovie_InvlaidInput() { 127 | //given 128 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 129 | Movie toyStory = new Movie(null, null, null, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 130 | 131 | //when 132 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.addNewMovie(toyStory)); 133 | 134 | } 135 | 136 | @Test 137 | void updateMovie() { 138 | //given 139 | String darkNightRisesCrew = "Tom Hardy"; 140 | Movie darkNightRises = new Movie(null, null, null, darkNightRisesCrew, null); 141 | Integer movieId = 3; 142 | 143 | //when 144 | Movie updatedMovie = moviesRestClient.updateMovie(movieId, darkNightRises); 145 | 146 | //then 147 | String updatedCastName = "Christian Bale, Heath Ledger , Michael Caine, Tom Hardy"; 148 | assertTrue(updatedMovie.getCast().contains(darkNightRisesCrew)); 149 | 150 | 151 | } 152 | 153 | @Test 154 | void updateMovie_Not_Found() { 155 | //given 156 | String darkNightRisesCrew = "Tom Hardy"; 157 | Movie darkNightRises = new Movie(null, null, null, darkNightRisesCrew, null); 158 | Integer movieId = 100; 159 | 160 | //when 161 | Assertions.assertThrows(MovieErrorResponse.class,()-> moviesRestClient.updateMovie(movieId, darkNightRises)); 162 | } 163 | 164 | @Test 165 | void deleteMovie() { 166 | 167 | //given 168 | String batmanBeginsCrew = "Tom Hanks, Tim Allen"; 169 | Movie toyStory = new Movie(null, "Toy Story 4", 2019, batmanBeginsCrew, LocalDate.of(2019, 06, 20)); 170 | Movie movie = moviesRestClient.addNewMovie(toyStory); 171 | Integer movieId=movie.getMovie_id().intValue(); 172 | 173 | //when 174 | String response = moviesRestClient.deleteMovieById(movieId); 175 | 176 | //then 177 | String expectedResponse = "Movie Deleted Successfully"; 178 | assertEquals(expectedResponse, response); 179 | 180 | } 181 | 182 | @Test 183 | void deleteMovie_notFound() { 184 | 185 | //given 186 | Integer movieId=100; 187 | 188 | //when 189 | Assertions.assertThrows(MovieErrorResponse.class, ()-> moviesRestClient.deleteMovieById(movieId)) ; 190 | 191 | } 192 | 193 | 194 | @Test 195 | @Disabled 196 | void getAllMovies_Exception() { 197 | Assertions.assertThrows(MovieErrorResponse.class, () -> moviesRestClient.retrieveAllMovies()); 198 | } 199 | 200 | } 201 | -------------------------------------------------------------------------------- /movies-restful-service/README.md: -------------------------------------------------------------------------------- 1 | # Movies RestFul WebService 2 | 3 | ## How to Run the app? 4 | 5 | - Run the below command in your machine. You must have java8 or higher to run this application. 6 | 7 | ``` 8 | java -jar movies-restful-service.jar 9 | ``` 10 | 11 | ## Swagger Link 12 | 13 | The below link will launch the swagger of the movies-restful-web-service. 14 | 15 | http://localhost:8081/movieservice/swagger-ui.html#/ 16 | -------------------------------------------------------------------------------- /movies-restful-service/movies-restful-service-beyond-java8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dilipsundarraj1/wiremock-for-java-developers/3321de471628cb58641f5aa021503dd5ff791872/movies-restful-service/movies-restful-service-beyond-java8.jar -------------------------------------------------------------------------------- /movies-restful-service/movies-restful-service-java8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dilipsundarraj1/wiremock-for-java-developers/3321de471628cb58641f5aa021503dd5ff791872/movies-restful-service/movies-restful-service-java8.jar --------------------------------------------------------------------------------