├── .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 | --------------------------------------------------------------------------------