├── .gitignore
├── .mvn
    └── wrapper
    │   ├── maven-wrapper.jar
    │   └── maven-wrapper.properties
├── .travis.yml
├── mvnw
├── mvnw.cmd
├── pom.xml
├── readme.md
└── src
    ├── main
        ├── asciidoc
        │   └── api-guide.adoc
        ├── java
        │   └── com
        │   │   └── example
        │   │       ├── TestingWithSpringBootApplication.java
        │   │       ├── annotation
        │   │           └── UseCase.java
        │   │       ├── domain
        │   │           ├── Car.java
        │   │           └── Money.java
        │   │       ├── external
        │   │           ├── data
        │   │           │   ├── CarEntity.java
        │   │           │   └── CarRepository.java
        │   │           └── dealer
        │   │           │   ├── DealerService.java
        │   │           │   └── Transaction.java
        │   │       ├── usecase
        │   │           ├── FindCar.java
        │   │           └── SellCar.java
        │   │       └── web
        │   │           ├── CarController.java
        │   │           └── NotFoundException.java
        └── resources
        │   ├── application.properties
        │   ├── data.sql
        │   └── schema.sql
    └── test
        ├── java
            └── com
            │   └── example
            │       ├── OutputCapturingTests.java
            │       ├── TestingWithSpringBootApplicationTests.java
            │       ├── external
            │           ├── data
            │           │   └── CarRepositoryIntegrationTests.java
            │           └── dealer
            │           │   ├── DealerServiceEndpoint.java
            │           │   ├── DealerServiceIntegrationTests.java
            │           │   └── TransactionJsonTests.java
            │       ├── usecase
            │           └── FindCarTests.java
            │       └── web
            │           ├── ApiDocumentation.java
            │           ├── CarControllerHtmlUnitTests.java
            │           ├── CarControllerRestTests.java
            │           ├── CarControllerSeleniumTests.java
            │           └── CarControllerTests.java
        └── resources
            └── application.properties
/.gitignore:
--------------------------------------------------------------------------------
 1 | # Created by .ignore support plugin (hsz.mobi)
 2 | ### Maven template
 3 | target/
 4 | pom.xml.tag
 5 | pom.xml.releaseBackup
 6 | pom.xml.versionsBackup
 7 | pom.xml.next
 8 | release.properties
 9 | dependency-reduced-pom.xml
10 | buildNumber.properties
11 | .mvn/timing.properties
12 | ### Eclipse template
13 | 
14 | .metadata
15 | bin/
16 | tmp/
17 | *.tmp
18 | *.bak
19 | *.swp
20 | *~.nib
21 | local.properties
22 | .settings/
23 | .loadpath
24 | .recommenders
25 | 
26 | # Eclipse Core
27 | .project
28 | 
29 | # External tool builders
30 | .externalToolBuilders/
31 | 
32 | # Locally stored "Eclipse launch configurations"
33 | *.launch
34 | 
35 | # PyDev specific (Python IDE for Eclipse)
36 | *.pydevproject
37 | 
38 | # CDT-specific (C/C++ Development Tooling)
39 | .cproject
40 | 
41 | # JDT-specific (Eclipse Java Development Tools)
42 | .classpath
43 | 
44 | # Java annotation processor (APT)
45 | .factorypath
46 | 
47 | # PDT-specific (PHP Development Tools)
48 | .buildpath
49 | 
50 | # sbteclipse plugin
51 | .target
52 | 
53 | # Tern plugin
54 | .tern-project
55 | 
56 | # TeXlipse plugin
57 | .texlipse
58 | 
59 | # STS (Spring Tool Suite)
60 | .springBeans
61 | 
62 | # Code Recommenders
63 | .recommenders/
64 | ### JetBrains template
65 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
66 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
67 | 
68 | # User-specific stuff:
69 | .idea
70 | 
71 | ## File-based project format:
72 | *.iws
73 | *.iml
74 | 
75 | ## Plugin-specific files:
76 | 
77 | # IntelliJ
78 | /out/
79 | 
80 | # mpeltonen/sbt-idea plugin
81 | .idea_modules/
82 | 
83 | # JIRA plugin
84 | atlassian-ide-plugin.xml
85 | 
86 | # Crashlytics plugin (for Android Studio and IntelliJ)
87 | com_crashlytics_export_strings.xml
88 | crashlytics.properties
89 | crashlytics-build.properties
90 | fabric.properties
91 | 
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mp911de/testing-with-spring-boot/a6556f4901eca2081b1067d923368a8a99c7b826/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
2 | 
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
 1 | language: java
 2 | 
 3 | jdk:
 4 |   - oraclejdk8
 5 | 
 6 | before_install:
 7 |   - sed -i.bak -e 's|https://nexus.codehaus.org/snapshots/|https://oss.sonatype.org/content/repositories/codehaus-snapshots/|g' ~/.m2/settings.xml
 8 | 
 9 | script: ./mvnw clean verify -P${PROFILE:-ci}
10 | 
11 | cache:
12 |   directories:
13 |     - '$HOME/.m2/repository'
14 | 
--------------------------------------------------------------------------------
/mvnw:
--------------------------------------------------------------------------------
  1 | #!/bin/sh
  2 | # ----------------------------------------------------------------------------
  3 | # Licensed to the Apache Software Foundation (ASF) under one
  4 | # or more contributor license agreements.  See the NOTICE file
  5 | # distributed with this work for additional information
  6 | # regarding copyright ownership.  The ASF licenses this file
  7 | # to you under the Apache License, Version 2.0 (the
  8 | # "License"); you may not use this file except in compliance
  9 | # with the License.  You may obtain a copy of the License at
 10 | #
 11 | #    http://www.apache.org/licenses/LICENSE-2.0
 12 | #
 13 | # Unless required by applicable law or agreed to in writing,
 14 | # software distributed under the License is distributed on an
 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 16 | # KIND, either express or implied.  See the License for the
 17 | # specific language governing permissions and limitations
 18 | # under the License.
 19 | # ----------------------------------------------------------------------------
 20 | 
 21 | # ----------------------------------------------------------------------------
 22 | # Maven2 Start Up Batch script
 23 | #
 24 | # Required ENV vars:
 25 | # ------------------
 26 | #   JAVA_HOME - location of a JDK home dir
 27 | #
 28 | # Optional ENV vars
 29 | # -----------------
 30 | #   M2_HOME - location of maven2's installed home dir
 31 | #   MAVEN_OPTS - parameters passed to the Java VM when running Maven
 32 | #     e.g. to debug Maven itself, use
 33 | #       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
 34 | #   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
 35 | # ----------------------------------------------------------------------------
 36 | 
 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
 38 | 
 39 |   if [ -f /etc/mavenrc ] ; then
 40 |     . /etc/mavenrc
 41 |   fi
 42 | 
 43 |   if [ -f "$HOME/.mavenrc" ] ; then
 44 |     . "$HOME/.mavenrc"
 45 |   fi
 46 | 
 47 | fi
 48 | 
 49 | # OS specific support.  $var _must_ be set to either true or false.
 50 | cygwin=false;
 51 | darwin=false;
 52 | mingw=false
 53 | case "`uname`" in
 54 |   CYGWIN*) cygwin=true ;;
 55 |   MINGW*) mingw=true;;
 56 |   Darwin*) darwin=true
 57 |            #
 58 |            # Look for the Apple JDKs first to preserve the existing behaviour, and then look
 59 |            # for the new JDKs provided by Oracle.
 60 |            #
 61 |            if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
 62 |              #
 63 |              # Apple JDKs
 64 |              #
 65 |              export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
 66 |            fi
 67 | 
 68 |            if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
 69 |              #
 70 |              # Apple JDKs
 71 |              #
 72 |              export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
 73 |            fi
 74 | 
 75 |            if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
 76 |              #
 77 |              # Oracle JDKs
 78 |              #
 79 |              export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
 80 |            fi
 81 | 
 82 |            if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
 83 |              #
 84 |              # Apple JDKs
 85 |              #
 86 |              export JAVA_HOME=`/usr/libexec/java_home`
 87 |            fi
 88 |            ;;
 89 | esac
 90 | 
 91 | if [ -z "$JAVA_HOME" ] ; then
 92 |   if [ -r /etc/gentoo-release ] ; then
 93 |     JAVA_HOME=`java-config --jre-home`
 94 |   fi
 95 | fi
 96 | 
 97 | if [ -z "$M2_HOME" ] ; then
 98 |   ## resolve links - $0 may be a link to maven's home
 99 |   PRG="$0"
100 | 
101 |   # need this for relative symlinks
102 |   while [ -h "$PRG" ] ; do
103 |     ls=`ls -ld "$PRG"`
104 |     link=`expr "$ls" : '.*-> \(.*\)$'`
105 |     if expr "$link" : '/.*' > /dev/null; then
106 |       PRG="$link"
107 |     else
108 |       PRG="`dirname "$PRG"`/$link"
109 |     fi
110 |   done
111 | 
112 |   saveddir=`pwd`
113 | 
114 |   M2_HOME=`dirname "$PRG"`/..
115 | 
116 |   # make it fully qualified
117 |   M2_HOME=`cd "$M2_HOME" && pwd`
118 | 
119 |   cd "$saveddir"
120 |   # echo Using m2 at $M2_HOME
121 | fi
122 | 
123 | # For Cygwin, ensure paths are in UNIX format before anything is touched
124 | if $cygwin ; then
125 |   [ -n "$M2_HOME" ] &&
126 |     M2_HOME=`cygpath --unix "$M2_HOME"`
127 |   [ -n "$JAVA_HOME" ] &&
128 |     JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
129 |   [ -n "$CLASSPATH" ] &&
130 |     CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
131 | fi
132 | 
133 | # For Migwn, ensure paths are in UNIX format before anything is touched
134 | if $mingw ; then
135 |   [ -n "$M2_HOME" ] &&
136 |     M2_HOME="`(cd "$M2_HOME"; pwd)`"
137 |   [ -n "$JAVA_HOME" ] &&
138 |     JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
139 |   # TODO classpath?
140 | fi
141 | 
142 | if [ -z "$JAVA_HOME" ]; then
143 |   javaExecutable="`which javac`"
144 |   if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
145 |     # readlink(1) is not available as standard on Solaris 10.
146 |     readLink=`which readlink`
147 |     if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
148 |       if $darwin ; then
149 |         javaHome="`dirname \"$javaExecutable\"`"
150 |         javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
151 |       else
152 |         javaExecutable="`readlink -f \"$javaExecutable\"`"
153 |       fi
154 |       javaHome="`dirname \"$javaExecutable\"`"
155 |       javaHome=`expr "$javaHome" : '\(.*\)/bin'`
156 |       JAVA_HOME="$javaHome"
157 |       export JAVA_HOME
158 |     fi
159 |   fi
160 | fi
161 | 
162 | if [ -z "$JAVACMD" ] ; then
163 |   if [ -n "$JAVA_HOME"  ] ; then
164 |     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
165 |       # IBM's JDK on AIX uses strange locations for the executables
166 |       JAVACMD="$JAVA_HOME/jre/sh/java"
167 |     else
168 |       JAVACMD="$JAVA_HOME/bin/java"
169 |     fi
170 |   else
171 |     JAVACMD="`which java`"
172 |   fi
173 | fi
174 | 
175 | if [ ! -x "$JAVACMD" ] ; then
176 |   echo "Error: JAVA_HOME is not defined correctly." >&2
177 |   echo "  We cannot execute $JAVACMD" >&2
178 |   exit 1
179 | fi
180 | 
181 | if [ -z "$JAVA_HOME" ] ; then
182 |   echo "Warning: JAVA_HOME environment variable is not set."
183 | fi
184 | 
185 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
186 | 
187 | # For Cygwin, switch paths to Windows format before running java
188 | if $cygwin; then
189 |   [ -n "$M2_HOME" ] &&
190 |     M2_HOME=`cygpath --path --windows "$M2_HOME"`
191 |   [ -n "$JAVA_HOME" ] &&
192 |     JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
193 |   [ -n "$CLASSPATH" ] &&
194 |     CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
195 | fi
196 | 
197 | # traverses directory structure from process work directory to filesystem root
198 | # first directory with .mvn subdirectory is considered project base directory
199 | find_maven_basedir() {
200 |   local basedir=$(pwd)
201 |   local wdir=$(pwd)
202 |   while [ "$wdir" != '/' ] ; do
203 |     if [ -d "$wdir"/.mvn ] ; then
204 |       basedir=$wdir
205 |       break
206 |     fi
207 |     wdir=$(cd "$wdir/.."; pwd)
208 |   done
209 |   echo "${basedir}"
210 | }
211 | 
212 | # concatenates all lines of a file
213 | concat_lines() {
214 |   if [ -f "$1" ]; then
215 |     echo "$(tr -s '\n' ' ' < "$1")"
216 |   fi
217 | }
218 | 
219 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
220 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
221 | 
222 | # Provide a "standardized" way to retrieve the CLI args that will
223 | # work with both Windows and non-Windows executions.
224 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
225 | export MAVEN_CMD_LINE_ARGS
226 | 
227 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
228 | 
229 | exec "$JAVACMD" \
230 |   $MAVEN_OPTS \
231 |   -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
232 |   "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
233 |   ${WRAPPER_LAUNCHER} "$@"
234 | 
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
  1 | @REM ----------------------------------------------------------------------------
  2 | @REM Licensed to the Apache Software Foundation (ASF) under one
  3 | @REM or more contributor license agreements.  See the NOTICE file
  4 | @REM distributed with this work for additional information
  5 | @REM regarding copyright ownership.  The ASF licenses this file
  6 | @REM to you under the Apache License, Version 2.0 (the
  7 | @REM "License"); you may not use this file except in compliance
  8 | @REM with the License.  You may obtain a copy of the License at
  9 | @REM
 10 | @REM    http://www.apache.org/licenses/LICENSE-2.0
 11 | @REM
 12 | @REM Unless required by applicable law or agreed to in writing,
 13 | @REM software distributed under the License is distributed on an
 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15 | @REM KIND, either express or implied.  See the License for the
 16 | @REM specific language governing permissions and limitations
 17 | @REM under the License.
 18 | @REM ----------------------------------------------------------------------------
 19 | 
 20 | @REM ----------------------------------------------------------------------------
 21 | @REM Maven2 Start Up Batch script
 22 | @REM
 23 | @REM Required ENV vars:
 24 | @REM JAVA_HOME - location of a JDK home dir
 25 | @REM
 26 | @REM Optional ENV vars
 27 | @REM M2_HOME - location of maven2's installed home dir
 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
 31 | @REM     e.g. to debug Maven itself, use
 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
 34 | @REM ----------------------------------------------------------------------------
 35 | 
 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
 37 | @echo off
 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
 39 | @if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
 40 | 
 41 | @REM set %HOME% to equivalent of $HOME
 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
 43 | 
 44 | @REM Execute a user defined script before this one
 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
 49 | :skipRcPre
 50 | 
 51 | @setlocal
 52 | 
 53 | set ERROR_CODE=0
 54 | 
 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
 56 | @setlocal
 57 | 
 58 | @REM ==== START VALIDATION ====
 59 | if not "%JAVA_HOME%" == "" goto OkJHome
 60 | 
 61 | echo.
 62 | echo Error: JAVA_HOME not found in your environment. >&2
 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
 64 | echo location of your Java installation. >&2
 65 | echo.
 66 | goto error
 67 | 
 68 | :OkJHome
 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
 70 | 
 71 | echo.
 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
 75 | echo location of your Java installation. >&2
 76 | echo.
 77 | goto error
 78 | 
 79 | @REM ==== END VALIDATION ====
 80 | 
 81 | :init
 82 | 
 83 | set MAVEN_CMD_LINE_ARGS=%*
 84 | 
 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
 86 | @REM Fallback to current working directory if not found.
 87 | 
 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
 90 | 
 91 | set EXEC_DIR=%CD%
 92 | set WDIR=%EXEC_DIR%
 93 | :findBaseDir
 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
 95 | cd ..
 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
 97 | set WDIR=%CD%
 98 | goto findBaseDir
 99 | 
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 | 
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 | 
109 | :endDetectBaseDir
110 | 
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 | 
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 | 
117 | :endReadAdditionalConfig
118 | 
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | 
121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 | 
124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
125 | if ERRORLEVEL 1 goto error
126 | goto end
127 | 
128 | :error
129 | set ERROR_CODE=1
130 | 
131 | :end
132 | @endlocal & set ERROR_CODE=%ERROR_CODE%
133 | 
134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
138 | :skipRcPost
139 | 
140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
142 | 
143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
144 | 
145 | exit /B %ERROR_CODE%
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
  1 | 
  2 | 
  4 | 	4.0.0
  5 | 
  6 | 	com.example
  7 | 	testing-with-spring-boot
  8 | 	1.0.0-SNAPSHOT
  9 | 	jar
 10 | 
 11 | 	testing-with-spring-boot
 12 | 	Testing with Spring Boot
 13 | 
 14 | 	
 15 | 		org.springframework.boot
 16 | 		spring-boot-starter-parent
 17 | 		1.5.8.RELEASE
 18 | 		 
 19 | 	
 20 | 
 21 | 	
 22 | 		UTF-8
 23 | 		UTF-8
 24 | 		1.8
 25 | 		3.8.0
 26 | 	
 27 | 
 28 | 	
 29 | 		
 30 | 			org.springframework.boot
 31 | 			spring-boot-starter-data-jpa
 32 | 		
 33 | 
 34 | 		
 35 | 			org.springframework.boot
 36 | 			spring-boot-starter-web
 37 | 		
 38 | 
 39 | 		
 40 | 			org.springframework.boot
 41 | 			spring-boot-starter-data-rest
 42 | 		
 43 | 
 44 | 		
 45 | 			mysql
 46 | 			mysql-connector-java
 47 | 		
 48 | 
 49 | 		
 50 | 			com.h2database
 51 | 			h2
 52 | 			runtime
 53 | 		
 54 | 
 55 | 		
 56 | 			org.projectlombok
 57 | 			lombok
 58 | 		
 59 | 
 60 | 		
 61 | 			org.springframework.boot
 62 | 			spring-boot-starter-test
 63 | 			test
 64 | 		
 65 | 
 66 | 		
 67 | 			org.springframework.restdocs
 68 | 			spring-restdocs-mockmvc
 69 | 			test
 70 | 		
 71 | 
 72 | 		
 73 | 			net.sourceforge.htmlunit
 74 | 			htmlunit
 75 | 			test
 76 | 		
 77 | 
 78 | 		
 79 | 			org.seleniumhq.selenium
 80 | 			selenium-api
 81 | 			test
 82 | 		
 83 | 
 84 | 		
 85 | 			org.seleniumhq.selenium
 86 | 			htmlunit-driver
 87 | 			test
 88 | 		
 89 | 	
 90 | 
 91 | 	
 92 | 		
 93 | 			
 94 | 				org.springframework.boot
 95 | 				spring-boot-maven-plugin
 96 | 			
 97 | 
 98 | 
 99 | 			
100 | 			
101 | 				org.apache.maven.plugins
102 | 				maven-surefire-plugin
103 | 				
104 | 					
105 | 						**/*Documentation.java
106 | 					
107 | 				
108 | 			
109 | 			
110 | 				org.asciidoctor
111 | 				asciidoctor-maven-plugin
112 | 				1.5.5
113 | 				
114 | 					
115 | 						generate-docs
116 | 						prepare-package
117 | 						
118 | 							process-asciidoc
119 | 						
120 | 						
121 | 							html
122 | 							book
123 | 							
124 | 								${project.build.directory}/generated-snippets
125 | 							
126 | 						
127 | 					
128 | 				
129 | 			
130 | 			
131 | 				maven-resources-plugin
132 | 				
133 | 					
134 | 						copy-resources
135 | 						prepare-package
136 | 						
137 | 							copy-resources
138 | 						
139 | 						
140 | 							${project.build.outputDirectory}/static/docs
141 | 							
142 | 								
143 | 									${project.build.directory}/generated-docs
144 | 								
145 | 							
146 | 						
147 | 					
148 | 				
149 | 			
150 | 			
151 | 		
152 | 	
153 | 
154 | 
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
 1 | # Testing with Spring Boot 1.5
 2 | 
 3 | This repository contains code to demonstrate the use of the new Spring Boot 1.5 testing support.
 4 | 
 5 | In particular it shows the usage of:
 6 | 
 7 | * AssertJ                     
 8 | * `@LocalServerPort` through [TestingWithSpringBootApplicationTests.java](src/test/java/com/example/TestingWithSpringBootApplicationTests.java)
 9 | * `@RestClientTest` through [DealerServiceIntegrationTests.java](src/test/java/com/example/external/dealer/DealerServiceIntegrationTests.java) 
10 | * `@JsonTest` through [TransactionJsonTests.java](src/test/java/com/example/external/dealer/TransactionJsonTests.java) 
11 | * `@DataJpaTest` through [CarRepositoryIntegrationTests.java](src/test/java/com/example/external/data/CarRepositoryIntegrationTests.java) 
12 | * `@MockBean` and `@WebMvcTest` through [CarControllerTests.java](src/test/java/com/example/web/CarControllerTests.java) 
13 | * `@WebMvcTest` with Selenium and HtmlUnit through [CarControllerSeleniumTests.java](src/test/java/com/example/web/CarControllerSeleniumTests.java) and [CarControllerHtmlUnitTests.java](src/test/java/com/example/web/CarControllerHtmlUnitTests.java) 
14 | * `TestRestTemplate` through [CarControllerRestTests.java](src/test/java/com/example/web/CarControllerSeleniumTests.java)
15 | * `@Rule OutputCapture` through through [OutputCapturingTests.java](src/test/java/com/example/OutputCapturingTests.java)
--------------------------------------------------------------------------------
/src/main/asciidoc/api-guide.adoc:
--------------------------------------------------------------------------------
 1 | = RESTful Notes API Guide
 2 | Mark Paluch;
 3 | :doctype: book
 4 | :icons: font
 5 | :source-highlighter: highlightjs
 6 | :toc: left
 7 | :toclevels: 4
 8 | :sectlinks:
 9 | 
10 | [[overview]]
11 | = Overview
12 | 
13 | [[overview-errors]]
14 | == Errors
15 | 
16 | Whenever an error response (status code >= 400) is returned, the body will contain a JSON object
17 | that describes the problem. The error object has the following structure:
18 | 
19 | include::{snippets}/error-example/response-fields.adoc[]
20 | 
21 | For example, a request that attempts to apply a non-existent tag to a note will produce a
22 | `400 Bad Request` response:
23 | 
24 | include::{snippets}/error-example/http-response.adoc[]
25 | 
26 | 
27 | [[resources]]
28 | = Resources
29 | 
30 | 
31 | 
32 | [[resources-index]]
33 | == Index
34 | 
35 | The index provides the entry point into the service.
36 | 
37 | 
38 | 
39 | [[resources-index-access]]
40 | === Accessing the index
41 | 
42 | A `GET` request is used to access the index
43 | 
44 | ==== Response structure
45 | 
46 | include::{snippets}/index-example/response-fields.adoc[]
47 | 
48 | ==== Example response
49 | 
50 | include::{snippets}/index-example/http-response.adoc[]
51 | 
52 | 
53 | 
54 | [[resources-index-links]]
55 | ==== Links
56 | 
57 | include::{snippets}/index-example/links.adoc[]
58 | 
59 | 
60 | 
61 | [[resources-cars]]
62 | == Cars
63 | 
64 | The Cars resources is used to create and list cars.
65 | 
66 | 
67 | 
68 | [[resources-cars-list]]
69 | === Listing cars
70 | 
71 | A `GET` request will list all of the service's notes.
72 | 
73 | ==== Response structure
74 | 
75 | include::{snippets}/cars-list-example/response-fields.adoc[]
76 | 
77 | ==== Example request
78 | 
79 | include::{snippets}/cars-list-example/curl-request.adoc[]
80 | 
81 | ==== Example response
82 | 
83 | include::{snippets}/cars-list-example/http-response.adoc[]
84 | 
85 | [[resources-notes-list-links]]
86 | ==== Links
87 | 
88 | include::{snippets}/cars-list-example/links.adoc[]
89 | 
90 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/TestingWithSpringBootApplication.java:
--------------------------------------------------------------------------------
 1 | package com.example;
 2 | 
 3 | import org.springframework.boot.SpringApplication;
 4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 | 
 6 | @SpringBootApplication
 7 | public class TestingWithSpringBootApplication {
 8 | 
 9 | 	public static void main(String[] args) {
10 | 		SpringApplication.run(TestingWithSpringBootApplication.class, args);
11 | 	}
12 | }
13 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/annotation/UseCase.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016-2017 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.annotation;
18 | 
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 | 
24 | import org.springframework.stereotype.Service;
25 | 
26 | /**
27 |  * Indicates that an annotated class is a "Usecase", originally defined by Object Oriented Software Engineering: A Use Case
28 |  * Driven Approach (Jacobson, 1992) as "a control object."
29 |  *
30 |  * @author Mark Paluch
31 |  */
32 | @Service
33 | @Target({ ElementType.TYPE })
34 | @Retention(RetentionPolicy.RUNTIME)
35 | public @interface UseCase {
36 | }
37 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/domain/Car.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.domain;
18 | 
19 | import lombok.AllArgsConstructor;
20 | import lombok.Data;
21 | import lombok.NoArgsConstructor;
22 | 
23 | /**
24 |  * @author Mark Paluch
25 |  */
26 | @Data
27 | @AllArgsConstructor
28 | @NoArgsConstructor
29 | public class Car {
30 |     private String name;
31 | }
32 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/domain/Money.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.domain;
18 | 
19 | import java.math.BigDecimal;
20 | import java.util.Currency;
21 | 
22 | import lombok.AllArgsConstructor;
23 | import lombok.Value;
24 | 
25 | /**
26 |  * @author Mark Paluch
27 |  */
28 | @Value
29 | @AllArgsConstructor
30 | public class Money {
31 | 
32 |     BigDecimal value;
33 |     Currency currency;
34 | }
35 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/external/data/CarEntity.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.external.data;
18 | 
19 | import javax.persistence.Entity;
20 | import javax.persistence.GeneratedValue;
21 | import javax.persistence.Id;
22 | import javax.persistence.Table;
23 | 
24 | import lombok.Data;
25 | import lombok.NoArgsConstructor;
26 | 
27 | /**
28 |  * @author Mark Paluch
29 |  */
30 | @Entity
31 | @Table(name = "CAR")
32 | @Data
33 | @NoArgsConstructor
34 | public class CarEntity {
35 | 
36 |     @Id
37 |     @GeneratedValue
38 |     private Long id;
39 | 
40 |     private String name;
41 | 
42 |     public CarEntity(String name) {
43 |         this.name = name;
44 |     }
45 | }
46 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/external/data/CarRepository.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.external.data;
18 | 
19 | import org.springframework.data.repository.CrudRepository;
20 | import org.springframework.data.rest.core.annotation.RestResource;
21 | 
22 | /**
23 |  * Repository for {@link CarEntity}.
24 |  *
25 |  * @author Mark Paluch
26 |  */
27 | @RestResource(path = "cars", rel = "cars")
28 | public interface CarRepository extends CrudRepository {
29 | 
30 |     CarEntity findByName(String name);
31 | 
32 | }
33 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/external/dealer/DealerService.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.external.dealer;
18 | 
19 | import java.math.BigDecimal;
20 | import java.util.Currency;
21 | 
22 | import org.springframework.beans.factory.annotation.Value;
23 | import org.springframework.boot.web.client.RestTemplateBuilder;
24 | import org.springframework.http.ResponseEntity;
25 | import org.springframework.stereotype.Service;
26 | import org.springframework.web.client.RestTemplate;
27 | 
28 | import com.example.domain.Car;
29 | import com.example.domain.Money;
30 | 
31 | /**
32 |  * Sells a car.
33 |  * 
34 |  * @author Mark Paluch
35 |  */
36 | @Service
37 | public class DealerService {
38 | 
39 |     private final RestTemplate restTemplate;
40 |     @Value("${dealer.service.value:http://my.dealer.service:9999}")
41 |     private String endpoint;
42 | 
43 |     public DealerService(RestTemplateBuilder builder) {
44 |         this.restTemplate = builder.build();
45 |     }
46 | 
47 |     public Money sell(Car car) {
48 | 
49 |         ResponseEntity response = restTemplate.postForEntity(String.format("%s/offers/{name}", endpoint), car,
50 |                 Transaction.class, car.getName());
51 | 
52 |         Transaction body = response.getBody();
53 | 
54 |         return new Money(new BigDecimal(body.getAmount()), Currency.getInstance(body.getCurrency()));
55 |     }
56 | }
57 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/external/dealer/Transaction.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.external.dealer;
18 | 
19 | import lombok.AllArgsConstructor;
20 | import lombok.Data;
21 | import lombok.NoArgsConstructor;
22 | 
23 | /**
24 |  * @author Mark Paluch
25 |  */
26 | @Data
27 | @AllArgsConstructor
28 | @NoArgsConstructor
29 | public class Transaction {
30 | 
31 |     private double amount;
32 |     private String currency;
33 | }
34 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/usecase/FindCar.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016-2017 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.usecase;
18 | 
19 | import java.util.Optional;
20 | 
21 | import lombok.RequiredArgsConstructor;
22 | 
23 | import com.example.annotation.UseCase;
24 | import com.example.domain.Car;
25 | import com.example.external.data.CarEntity;
26 | import com.example.external.data.CarRepository;
27 | 
28 | /**
29 |  * @author Mark Paluch
30 |  */
31 | @UseCase
32 | @RequiredArgsConstructor
33 | public class FindCar {
34 | 
35 |     private final CarRepository carRepository;
36 | 
37 |     public Optional findCar(String name) {
38 | 
39 |         CarEntity carEntity = carRepository.findByName(name);
40 | 
41 |         return Optional.ofNullable(carEntity).map(CarEntity::getName).map(Car::new);
42 |     }
43 | }
44 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/usecase/SellCar.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016-2017 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.usecase;
18 | 
19 | import lombok.AccessLevel;
20 | import lombok.RequiredArgsConstructor;
21 | import lombok.experimental.FieldDefaults;
22 | 
23 | import com.example.annotation.UseCase;
24 | import com.example.domain.Car;
25 | import com.example.domain.Money;
26 | import com.example.external.dealer.DealerService;
27 | 
28 | /**
29 |  * @author Mark Paluch
30 |  */
31 | @UseCase
32 | @RequiredArgsConstructor
33 | @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
34 | public class SellCar {
35 | 
36 |     DealerService dealerService;
37 |     FindCar findCar;
38 | 
39 |     public Money sellCar(String name) {
40 | 
41 |         Car car = findCar.findCar(name).orElseThrow(() -> new IllegalStateException(String.format("Car %s not found", name)));
42 | 
43 |         return dealerService.sell(car);
44 |     }
45 | }
46 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/web/CarController.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016-2017 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.web;
18 | 
19 | import java.util.Optional;
20 | 
21 | import org.springframework.http.HttpStatus;
22 | import org.springframework.http.MediaType;
23 | import org.springframework.http.ResponseEntity;
24 | import org.springframework.web.bind.annotation.*;
25 | 
26 | import com.example.domain.Car;
27 | import com.example.domain.Money;
28 | import com.example.usecase.FindCar;
29 | import com.example.usecase.SellCar;
30 | 
31 | /**
32 |  * @author Mark Paluch
33 |  */
34 | @RestController
35 | public class CarController {
36 | 
37 |     private final FindCar findCar;
38 |     private final SellCar sellCar;
39 | 
40 |     public CarController(FindCar findCar, SellCar sellCar) {
41 |         this.findCar = findCar;
42 |         this.sellCar = sellCar;
43 |     }
44 | 
45 |     @GetMapping(value = "/cars/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
46 |     public Car findCarJson(@PathVariable String name) {
47 |         return getCar(name);
48 |     }
49 | 
50 |     private Car getCar(String name) {
51 |         return findCar.findCar(name).orElseThrow(NotFoundException::new);
52 |     }
53 | 
54 |     @GetMapping(value = "/cars/{name}.html", produces = MediaType.TEXT_HTML_VALUE)
55 |     public ResponseEntity findCarHtml(@PathVariable String name) {
56 | 
57 |         Optional car = findCar.findCar(name);
58 | 
59 |         return car //
60 |                 .map((body) -> ResponseEntity.ok(String.format("Car
Found %s
", body.getName()))) //
61 |                 .orElse(ResponseEntity.status(HttpStatus.NOT_FOUND).body(
62 |                         String.format("Not Found
Cannot find %s
", name)));
63 |     }
64 | 
65 |     @DeleteMapping("/cars/{name}")
66 |     public Money sellCar(@PathVariable String name) {
67 |         return sellCar.sellCar(name);
68 |     }
69 | 
70 |     @ExceptionHandler
71 |     @ResponseStatus(HttpStatus.NOT_FOUND)
72 |     private void handleNotFoundException(NotFoundException e) {
73 |     }
74 | }
75 | 
--------------------------------------------------------------------------------
/src/main/java/com/example/web/NotFoundException.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016-2017 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.web;
18 | 
19 | /**
20 |  * @author Mark Paluch
21 |  */
22 | public class NotFoundException extends RuntimeException {
23 | }
24 | 
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.jpa.hibernate.ddl-auto=none
2 | 
--------------------------------------------------------------------------------
/src/main/resources/data.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO CAR(id, name) values(1, 'Honda');
2 | INSERT INTO CAR(id, name) values(2, 'Audi');
3 | 
4 | 
--------------------------------------------------------------------------------
/src/main/resources/schema.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS CAR;
2 | CREATE TABLE CAR(
3 |   id BIGINT AUTO_INCREMENT PRIMARY KEY,
4 |   name VARCHAR(255)
5 | );
6 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/OutputCapturingTests.java:
--------------------------------------------------------------------------------
 1 | package com.example;
 2 | 
 3 | import static org.hamcrest.Matchers.containsString;
 4 | 
 5 | import org.junit.Rule;
 6 | import org.junit.Test;
 7 | 
 8 | import org.springframework.boot.test.rule.OutputCapture;
 9 | 
10 | /**
11 |  * Test expecting some output on sysout.
12 |  *
13 |  * @author Mark Paluch
14 |  */
15 | public class OutputCapturingTests {
16 | 
17 | 	@Rule public final OutputCapture outputCapture = new OutputCapture();
18 | 
19 | 	@Test
20 | 	public void shouldOutputAString() {
21 | 
22 | 		outputCapture.expect(containsString("expected on sysout"));
23 | 
24 | 		System.out.println("Hello, I'm expected on sysout");
25 | 	}
26 | }
27 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/TestingWithSpringBootApplicationTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example;
18 | 
19 | import static org.assertj.core.api.Assertions.*;
20 | 
21 | import org.junit.Test;
22 | import org.junit.runner.RunWith;
23 | import org.springframework.beans.factory.annotation.Value;
24 | import org.springframework.boot.test.context.SpringBootTest;
25 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
26 | import org.springframework.http.HttpStatus;
27 | import org.springframework.http.ResponseEntity;
28 | import org.springframework.test.context.junit4.SpringRunner;
29 | import org.springframework.web.client.RestTemplate;
30 | 
31 | /**
32 |  * Integration test for the whole application.
33 |  *
34 |  * @author Mark Paluch
35 |  */
36 | @RunWith(SpringRunner.class)
37 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
38 | public class TestingWithSpringBootApplicationTests {
39 | 
40 |     @Value("${local.server.port}")
41 |     private int localServerPort;
42 | 
43 |     @Test
44 |     public void contextLoads() {
45 |     }
46 | 
47 |     @Test
48 |     public void test() {
49 | 
50 |         RestTemplate restTemplate = new RestTemplate();
51 |         ResponseEntity response = restTemplate.getForEntity("http://localhost:{port}/cars/{name}", String.class,
52 |                 localServerPort, "Honda");
53 | 
54 |         assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
55 |         assertThat(response.getBody()).contains("Honda");
56 |     }
57 | }
58 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/external/data/CarRepositoryIntegrationTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016-2017 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.external.data;
18 | 
19 | import static org.assertj.core.api.Assertions.assertThat;
20 | 
21 | import org.junit.Test;
22 | import org.junit.runner.RunWith;
23 | import org.springframework.beans.factory.annotation.Autowired;
24 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
25 | import org.springframework.boot.test.context.SpringBootTest;
26 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
27 | import org.springframework.test.context.junit4.SpringRunner;
28 | 
29 | /**
30 |  * @author Mark Paluch
31 |  */
32 | @RunWith(SpringJUnit4ClassRunner.class)
33 | @SpringBootTest
34 | public class CarRepositoryIntegrationTests {
35 | 
36 |     @Autowired
37 |     CarRepository carRepository;
38 | 
39 |     @Test
40 |     public void shouldFindByName() {
41 | 
42 |         carRepository.save(new CarEntity("Multivan"));
43 | 
44 |         CarEntity present = carRepository.findByName("Multivan");
45 | 
46 |         assertThat(present).isNotNull();
47 |     }
48 | 
49 |     @Test
50 |     public void shouldNotFindByName() {
51 | 
52 |         CarEntity absent = carRepository.findByName("Unknown");
53 | 
54 |         assertThat(absent).isNull();
55 |     }
56 | }
57 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/external/dealer/DealerServiceEndpoint.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.external.dealer;
18 | 
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 | 
24 | import org.springframework.boot.test.autoconfigure.properties.PropertyMapping;
25 | 
26 | /**
27 |  * @author Mark Paluch
28 |  */
29 | @Target(ElementType.TYPE)
30 | @Retention(RetentionPolicy.RUNTIME)
31 | @PropertyMapping("dealer.service")
32 | public @interface DealerServiceEndpoint {
33 |     String value();
34 | }
35 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/external/dealer/DealerServiceIntegrationTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.external.dealer;
18 | 
19 | import static org.assertj.core.api.Assertions.*;
20 | import static org.springframework.test.web.client.match.MockRestRequestMatchers.*;
21 | import static org.springframework.test.web.client.response.MockRestResponseCreators.*;
22 | 
23 | import java.math.BigDecimal;
24 | import java.util.Currency;
25 | 
26 | import org.junit.Test;
27 | import org.junit.runner.RunWith;
28 | import org.springframework.beans.factory.annotation.Autowired;
29 | import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
30 | import org.springframework.http.MediaType;
31 | import org.springframework.test.context.junit4.SpringRunner;
32 | import org.springframework.test.web.client.MockRestServiceServer;
33 | 
34 | import com.example.domain.Car;
35 | import com.example.domain.Money;
36 | 
37 | /**
38 |  * @author Mark Paluch
39 |  */
40 | @RunWith(SpringRunner.class)
41 | @RestClientTest(DealerService.class)
42 | @DealerServiceEndpoint("http://localhost:8081")
43 | public class DealerServiceIntegrationTests {
44 | 
45 |     @Autowired
46 |     private DealerService sut;
47 | 
48 |     @Autowired
49 |     private MockRestServiceServer server;
50 | 
51 |     @Test
52 |     public void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails() throws Exception {
53 | 
54 |         this.server.expect(requestTo("http://localhost:8081/offers/Honda"))
55 |                 .andRespond(withSuccess("{\"amount\": 42, \"currency\": \"USD\"}", MediaType.APPLICATION_JSON));
56 | 
57 |         Money bucks = sut.sell(new Car("Honda"));
58 | 
59 |         assertThat(bucks.getValue()).isEqualTo(BigDecimal.valueOf(42));
60 |         assertThat(bucks.getCurrency()).isEqualTo(Currency.getInstance("USD"));
61 |     }
62 | }
--------------------------------------------------------------------------------
/src/test/java/com/example/external/dealer/TransactionJsonTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.external.dealer;
18 | 
19 | import static org.assertj.core.api.Assertions.*;
20 | 
21 | import org.junit.Test;
22 | import org.junit.runner.RunWith;
23 | import org.springframework.beans.factory.annotation.Autowired;
24 | import org.springframework.boot.test.autoconfigure.json.JsonTest;
25 | import org.springframework.boot.test.json.JacksonTester;
26 | import org.springframework.test.context.junit4.SpringRunner;
27 | 
28 | /**
29 |  * JSON representation test for {@link com.example.domain.Money}.
30 |  *
31 |  * @author Mark Paluch
32 |  */
33 | @RunWith(SpringRunner.class)
34 | @JsonTest
35 | public class TransactionJsonTests {
36 | 
37 |     @Autowired
38 |     private JacksonTester json;
39 | 
40 |     @Test
41 |     public void serializeJson() throws Exception {
42 | 
43 |         Transaction transaction = new Transaction(42, "USD");
44 | 
45 |         assertThat(this.json.write(transaction)).isEqualTo("{\"amount\":42, \"currency\":\"USD\"}");
46 |     }
47 | 
48 |     @Test
49 |     public void deserializeJson() throws Exception {
50 | 
51 |         String content = "{\"amount\":42, \"currency\":\"USD\"}";
52 | 
53 |         assertThat(this.json.parse(content)).isEqualTo(new Transaction(42, "USD"));
54 |         assertThat(this.json.parseObject(content).getAmount()).isEqualTo(42);
55 |     }
56 | }
57 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/usecase/FindCarTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016-2017 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.usecase;
18 | 
19 | import static org.assertj.core.api.Assertions.*;
20 | import static org.mockito.Mockito.*;
21 | 
22 | import java.util.Optional;
23 | 
24 | import org.junit.Before;
25 | import org.junit.Test;
26 | import org.mockito.Mock;
27 | import org.mockito.MockitoAnnotations;
28 | 
29 | import com.example.domain.Car;
30 | import com.example.external.data.CarEntity;
31 | import com.example.external.data.CarRepository;
32 | 
33 | /**
34 |  * Unit test for {@link FindCar}.
35 |  *
36 |  * @author Mark Paluch
37 |  */
38 | public class FindCarTests {
39 | 
40 |     private FindCar sut;
41 | 
42 |     @Mock
43 |     private CarRepository carRepositoryMock;
44 | 
45 |     @Before
46 |     public void before() {
47 | 
48 |         MockitoAnnotations.initMocks(this);
49 | 
50 |         sut = new FindCar(carRepositoryMock);
51 |     }
52 | 
53 |     @Test
54 |     public void shouldNotFindCar() {
55 | 
56 |         Optional absent = sut.findCar("absent");
57 | 
58 |         assertThat(absent).isNotPresent();
59 |     }
60 | 
61 |     @Test
62 |     public void shouldFindCar() {
63 | 
64 |         when(carRepositoryMock.findByName("Honda")).thenReturn(new CarEntity("Honda"));
65 | 
66 |         Optional present = sut.findCar("Honda");
67 | 
68 |         assertThat(present).isPresent().map(Car::getName).contains("Honda");
69 |     }
70 | }
71 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/web/ApiDocumentation.java:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * Copyright 2016 the original author or authors.
  3 |  *
  4 |  * Licensed under the Apache License, Version 2.0 (the "License");
  5 |  * you may not use this file except in compliance with the License.
  6 |  * You may obtain a copy of the License at
  7 |  *
  8 |  *      http://www.apache.org/licenses/LICENSE-2.0
  9 |  *
 10 |  * Unless required by applicable law or agreed to in writing, software
 11 |  * distributed under the License is distributed on an "AS IS" BASIS,
 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13 |  * See the License for the specific language governing permissions and
 14 |  * limitations under the License.
 15 |  */
 16 | 
 17 | package com.example.web;
 18 | 
 19 | import static org.hamcrest.Matchers.is;
 20 | import static org.hamcrest.Matchers.notNullValue;
 21 | import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
 22 | import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
 23 | import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
 24 | import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
 25 | import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
 26 | import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
 27 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
 28 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
 29 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 30 | 
 31 | import javax.servlet.RequestDispatcher;
 32 | 
 33 | import org.junit.Test;
 34 | import org.junit.runner.RunWith;
 35 | 
 36 | import org.springframework.beans.factory.annotation.Autowired;
 37 | import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
 38 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 39 | import org.springframework.boot.test.context.SpringBootTest;
 40 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
 41 | import org.springframework.test.context.junit4.SpringRunner;
 42 | import org.springframework.test.web.servlet.MockMvc;
 43 | 
 44 | import com.example.TestingWithSpringBootApplication;
 45 | import com.example.external.data.CarEntity;
 46 | import com.example.external.data.CarRepository;
 47 | 
 48 | /**
 49 |  * API Documentation with Spring REST Docs.
 50 |  *
 51 |  * @author Mark Paluch
 52 |  */
 53 | @RunWith(SpringRunner.class)
 54 | @AutoConfigureRestDocs("target/generated-snippets")
 55 | @SpringBootTest(webEnvironment = WebEnvironment.MOCK, classes = TestingWithSpringBootApplication.class)
 56 | @AutoConfigureMockMvc
 57 | public class ApiDocumentation {
 58 | 
 59 |     @Autowired
 60 |     private CarRepository carRepository;
 61 | 
 62 |     @Autowired
 63 |     private MockMvc mockMvc;
 64 | 
 65 |     @Test
 66 |     public void errorExample() throws Exception {
 67 | 
 68 |         this.mockMvc
 69 |                 .perform(
 70 |                         get("/error")
 71 |                                 .requestAttr(RequestDispatcher.ERROR_STATUS_CODE, 400)
 72 |                                 .requestAttr(RequestDispatcher.ERROR_REQUEST_URI, "/cars")
 73 |                                 .requestAttr(RequestDispatcher.ERROR_MESSAGE,
 74 |                                         "The car 'http://localhost:8080/cars/123' does not exist"))
 75 |                 .andDo(print())
 76 |                 .andExpect(status().isBadRequest())
 77 |                 .andExpect(jsonPath("error", is("Bad Request")))
 78 |                 .andExpect(jsonPath("timestamp", is(notNullValue())))
 79 |                 .andExpect(jsonPath("status", is(400)))
 80 |                 .andExpect(jsonPath("path", is(notNullValue())))
 81 |                 .andDo(document(
 82 |                         "error-example",
 83 |                         responseFields(fieldWithPath("error").description("The HTTP error that occurred, e.g. `Bad Request`"),
 84 |                                 fieldWithPath("message").description("A description of the cause of the error"),
 85 |                                 fieldWithPath("path").description("The path to which the request was made"),
 86 |                                 fieldWithPath("status").description("The HTTP status code, e.g. `400`"),
 87 |                                 fieldWithPath("timestamp")
 88 |                                         .description("The time, in milliseconds, at which the error occurred"))));
 89 |     }
 90 | 
 91 |     @Test
 92 |     public void indexExample() throws Exception {
 93 | 
 94 |         this.mockMvc
 95 |                 .perform(get("/"))
 96 |                 .andExpect(status().isOk())
 97 |                 .andDo(document(
 98 |                         "index-example",
 99 |                         links(linkWithRel("cars").description("The <>"), linkWithRel("profile")
100 |                                 .description("The ALPS profile for the service")), responseFields(fieldWithPath("_links")
101 |                                 .description("<> to other resources"))));
102 | 
103 |     }
104 | 
105 |     @Test
106 |     public void carRepositoryListExample() throws Exception {
107 | 
108 |         this.carRepository.deleteAll();
109 | 
110 |         carRepository.save(new CarEntity("Audi"));
111 |         carRepository.save(new CarEntity("Honda"));
112 | 
113 |         this.mockMvc
114 |                 .perform(get("/cars"))
115 |                 .andExpect(status().isOk())
116 |                 .andDo(document(
117 |                         "cars-list-example",
118 |                         links(linkWithRel("self").description("Canonical link for this resource"), linkWithRel("search")
119 |                                 .description("Search link for this resource"),
120 |                                 linkWithRel("profile").description("The ALPS profile for this resource")),
121 |                         responseFields(
122 |                                 fieldWithPath("_embedded.cars").description("An array of <>"),
123 |                                 fieldWithPath("_links").description("<> to other resources"))));
124 |     }
125 | 
126 | }
127 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/web/CarControllerHtmlUnitTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.web;
18 | 
19 | import static org.assertj.core.api.Assertions.*;
20 | import static org.mockito.Mockito.*;
21 | 
22 | import java.util.Optional;
23 | 
24 | import org.junit.Test;
25 | import org.junit.runner.RunWith;
26 | import org.springframework.beans.factory.annotation.Autowired;
27 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
28 | import org.springframework.boot.test.mock.mockito.MockBean;
29 | import org.springframework.test.context.junit4.SpringRunner;
30 | 
31 | import com.example.domain.Car;
32 | import com.example.usecase.FindCar;
33 | import com.example.usecase.SellCar;
34 | import com.gargoylesoftware.htmlunit.WebClient;
35 | import com.gargoylesoftware.htmlunit.html.HtmlPage;
36 | 
37 | /**
38 |  * HtmlUnit Tests for {@link CarController}.
39 |  * 
40 |  * @author Mark Paluch
41 |  */
42 | @RunWith(SpringRunner.class)
43 | @WebMvcTest(CarController.class)
44 | public class CarControllerHtmlUnitTests {
45 | 
46 |     @Autowired
47 |     private WebClient webClient;
48 | 
49 |     @MockBean
50 |     private FindCar findCar;
51 | 
52 |     @MockBean
53 |     private SellCar sellCar;
54 | 
55 |     @Test
56 |     public void findCarShouldReturnCar() throws Exception {
57 | 
58 |         when(findCar.findCar("Honda")).thenReturn(Optional.of(new Car("Honda")));
59 | 
60 |         HtmlPage htmlPage = this.webClient.getPage("/cars/Honda.html");
61 |         assertThat(htmlPage.getBody().getTextContent()).contains("Found Honda");
62 |     }
63 | 
64 |     @Test
65 |     public void findCarShouldAbsentCar() throws Exception {
66 | 
67 |         when(findCar.findCar("Other")).thenReturn(Optional.empty());
68 | 
69 | 		this.webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
70 | 
71 | 		HtmlPage htmlPage = this.webClient.getPage("/cars/Other.html");
72 |         assertThat(htmlPage.getBody().getTextContent()).contains("Cannot find Other");
73 |     }
74 | }
--------------------------------------------------------------------------------
/src/test/java/com/example/web/CarControllerRestTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016-2017 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.web;
18 | 
19 | import static org.assertj.core.api.Assertions.*;
20 | import static org.mockito.Mockito.*;
21 | import static org.springframework.boot.test.context.SpringBootTest.*;
22 | 
23 | import java.util.Optional;
24 | 
25 | import org.junit.Test;
26 | import org.junit.runner.RunWith;
27 | import org.springframework.beans.factory.annotation.Autowired;
28 | import org.springframework.boot.test.context.SpringBootTest;
29 | import org.springframework.boot.test.mock.mockito.MockBean;
30 | import org.springframework.boot.test.web.client.TestRestTemplate;
31 | import org.springframework.http.HttpStatus;
32 | import org.springframework.http.ResponseEntity;
33 | import org.springframework.test.context.junit4.SpringRunner;
34 | 
35 | import com.example.domain.Car;
36 | import com.example.usecase.FindCar;
37 | import com.example.usecase.SellCar;
38 | 
39 | /**
40 |  * Tests for {@link CarController}.
41 |  *
42 |  * @author Mark Paluch
43 |  */
44 | @RunWith(SpringRunner.class)
45 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
46 | public class CarControllerRestTests {
47 | 
48 |     @Autowired
49 |     private TestRestTemplate restTemplate;
50 | 
51 |     @MockBean
52 |     private FindCar findCar;
53 | 
54 |     @MockBean
55 |     private SellCar sellCar;
56 | 
57 |     @Test
58 |     public void findCarShouldReturnCar() {
59 | 
60 |         when(findCar.findCar("Honda")).thenReturn(Optional.of(new Car("Honda")));
61 | 
62 |         ResponseEntity honda = restTemplate.getForEntity("/cars/{car}", Car.class, "Honda");
63 | 
64 |         assertThat(honda.getStatusCode()).isEqualTo(HttpStatus.OK);
65 |         assertThat(honda.getBody().getName()).isEqualTo("Honda");
66 |     }
67 | }
68 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/web/CarControllerSeleniumTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.web;
18 | 
19 | import static org.assertj.core.api.Assertions.*;
20 | import static org.mockito.Mockito.*;
21 | 
22 | import java.util.Optional;
23 | 
24 | import org.junit.Test;
25 | import org.junit.runner.RunWith;
26 | import org.openqa.selenium.By;
27 | import org.openqa.selenium.WebDriver;
28 | import org.springframework.beans.factory.annotation.Autowired;
29 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
30 | import org.springframework.boot.test.mock.mockito.MockBean;
31 | import org.springframework.test.context.junit4.SpringRunner;
32 | 
33 | import com.example.domain.Car;
34 | import com.example.usecase.FindCar;
35 | import com.example.usecase.SellCar;
36 | 
37 | /**
38 |  * Selenium Tests for {@link CarController}.
39 |  *
40 |  * @author Mark Paluch
41 |  */
42 | @RunWith(SpringRunner.class)
43 | @WebMvcTest(CarController.class)
44 | public class CarControllerSeleniumTests {
45 | 
46 |     @Autowired
47 |     private WebDriver webDriver;
48 | 
49 |     @MockBean
50 |     private FindCar findCar;
51 | 
52 | 	@MockBean
53 |     private SellCar sellCar;
54 | 
55 |     @Test
56 |     public void findCarShouldReturnCar() {
57 | 
58 |         when(findCar.findCar("Honda")).thenReturn(Optional.of(new Car("Honda")));
59 | 
60 |         this.webDriver.get("/cars/Honda.html");
61 |         assertThat(webDriver.findElement(By.tagName("h1")).getText()).isEqualTo("Car");
62 |         assertThat(webDriver.findElement(By.tagName("p")).getText()).isEqualTo("Found Honda");
63 |     }
64 | 
65 | }
66 | 
--------------------------------------------------------------------------------
/src/test/java/com/example/web/CarControllerTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright 2016 the original author or authors.
 3 |  *
 4 |  * Licensed under the Apache License, Version 2.0 (the "License");
 5 |  * you may not use this file except in compliance with the License.
 6 |  * You may obtain a copy of the License at
 7 |  *
 8 |  *      http://www.apache.org/licenses/LICENSE-2.0
 9 |  *
10 |  * Unless required by applicable law or agreed to in writing, software
11 |  * distributed under the License is distributed on an "AS IS" BASIS,
12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  * See the License for the specific language governing permissions and
14 |  * limitations under the License.
15 |  */
16 | 
17 | package com.example.web;
18 | 
19 | import static org.mockito.Mockito.*;
20 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
22 | 
23 | import java.util.Optional;
24 | 
25 | import org.junit.Test;
26 | import org.junit.runner.RunWith;
27 | import org.springframework.beans.factory.annotation.Autowired;
28 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
29 | import org.springframework.boot.test.mock.mockito.MockBean;
30 | import org.springframework.http.MediaType;
31 | import org.springframework.test.context.junit4.SpringRunner;
32 | import org.springframework.test.web.servlet.MockMvc;
33 | 
34 | import com.example.domain.Car;
35 | import com.example.usecase.FindCar;
36 | import com.example.usecase.SellCar;
37 | 
38 | /**
39 |  * Tests for {@link CarController}.
40 |  * 
41 |  * @author Mark Paluch
42 |  */
43 | @RunWith(SpringRunner.class)
44 | @WebMvcTest(CarController.class)
45 | public class CarControllerTests {
46 | 
47 |     @Autowired
48 |     private MockMvc mvc;
49 | 
50 |     @MockBean
51 |     private FindCar findCar;
52 | 
53 |     @MockBean
54 |     private SellCar sellCar;
55 | 
56 |     @Test
57 |     public void findCarShouldReturnCar() throws Exception {
58 | 
59 |         when(findCar.findCar("Honda")).thenReturn(Optional.of(new Car("Honda")));
60 | 
61 |         mvc.perform(get("/cars/Honda").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
62 |                 .andExpect(content().json("{ 'name': 'Honda' }"));
63 |     }
64 | 
65 |     @Test
66 |     public void findCarShouldReturn404WhenNoCarIsFound() throws Exception {
67 | 
68 |     	when(findCar.findCar(anyString())).thenReturn(Optional.empty());
69 | 
70 |         mvc.perform(get("/cars/Unknown").accept(MediaType.APPLICATION_JSON)).andExpect(status().isNotFound());
71 |     }
72 | }
--------------------------------------------------------------------------------
/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.jackson.serialization.indent_output=true
2 | spring.jpa.hibernate.ddl-auto=none
3 | spring.datasource.url=jdbc:mysql://localhost/springboot
4 | spring.datasource.username=springboot
5 | spring.datasource.password=springboot
6 | 
--------------------------------------------------------------------------------