Group testing modules (#3014)
* move security content from spring-security-rest-full * swagger update * move query language to new module * rename spring-security-rest-full to spring-rest-full * group persistence modules * group testing modules * try fix conflict
This commit is contained in:
committed by
GitHub
parent
b383d83bf4
commit
776a01429e
@@ -0,0 +1,2 @@
|
||||
### Relevant Articles:
|
||||
- [Intro to Gatling](http://www.baeldung.com/introduction-to-gatling)
|
||||
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.baeldung</groupId>
|
||||
<artifactId>gatling</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<scala.version>2.11.7</scala.version>
|
||||
<encoding>UTF-8</encoding>
|
||||
<gatling.version>2.2.0</gatling.version>
|
||||
<scala-maven-plugin.version>3.2.2</scala-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.gatling</groupId>
|
||||
<artifactId>gatling-app</artifactId>
|
||||
<version>${gatling.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.gatling</groupId>
|
||||
<artifactId>gatling-recorder</artifactId>
|
||||
<version>${gatling.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.gatling.highcharts</groupId>
|
||||
<artifactId>gatling-charts-highcharts</artifactId>
|
||||
<version>${gatling.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-library</artifactId>
|
||||
<version>${scala.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.gatling.highcharts</groupId>
|
||||
<artifactId>gatling-charts-highcharts</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.gatling</groupId>
|
||||
<artifactId>gatling-app</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.gatling</groupId>
|
||||
<artifactId>gatling-recorder</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-library</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<testSourceDirectory>src/test/scala</testSourceDirectory>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<version>${scala-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<args>
|
||||
<arg>-Ybackend:GenBCode</arg>
|
||||
<arg>-Ydelambdafy:method</arg>
|
||||
<arg>-target:jvm-1.8</arg>
|
||||
<arg>-deprecation</arg>
|
||||
<arg>-feature</arg>
|
||||
<arg>-unchecked</arg>
|
||||
<arg>-language:implicitConversions</arg>
|
||||
<arg>-language:postfixOps</arg>
|
||||
</args>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.gatling</groupId>
|
||||
<artifactId>gatling-maven-plugin</artifactId>
|
||||
<version>${gatling.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>test</phase>
|
||||
<goals><goal>execute</goal></goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,127 @@
|
||||
#########################
|
||||
# Gatling Configuration #
|
||||
#########################
|
||||
|
||||
# This file contains all the settings configurable for Gatling with their default values
|
||||
|
||||
gatling {
|
||||
core {
|
||||
#outputDirectoryBaseName = "" # The prefix for each simulation result folder (then suffixed by the report generation timestamp)
|
||||
#runDescription = "" # The description for this simulation run, displayed in each report
|
||||
#encoding = "utf-8" # Encoding to use throughout Gatling for file and string manipulation
|
||||
#simulationClass = "" # The FQCN of the simulation to run (when used in conjunction with noReports, the simulation for which assertions will be validated)
|
||||
#mute = false # When set to true, don't ask for simulation name nor run description (currently only used by Gatling SBT plugin)
|
||||
#elFileBodiesCacheMaxCapacity = 200 # Cache size for request body EL templates, set to 0 to disable
|
||||
#rawFileBodiesCacheMaxCapacity = 200 # Cache size for request body Raw templates, set to 0 to disable
|
||||
#rawFileBodiesInMemoryMaxSize = 1000 # Below this limit, raw file bodies will be cached in memory
|
||||
|
||||
extract {
|
||||
regex {
|
||||
#cacheMaxCapacity = 200 # Cache size for the compiled regexes, set to 0 to disable caching
|
||||
}
|
||||
xpath {
|
||||
#cacheMaxCapacity = 200 # Cache size for the compiled XPath queries, set to 0 to disable caching
|
||||
}
|
||||
jsonPath {
|
||||
#cacheMaxCapacity = 200 # Cache size for the compiled jsonPath queries, set to 0 to disable caching
|
||||
#preferJackson = false # When set to true, prefer Jackson over Boon for JSON-related operations
|
||||
}
|
||||
css {
|
||||
#cacheMaxCapacity = 200 # Cache size for the compiled CSS selectors queries, set to 0 to disable caching
|
||||
}
|
||||
}
|
||||
|
||||
directory {
|
||||
#data = user-files/data # Folder where user's data (e.g. files used by Feeders) is located
|
||||
#bodies = user-files/bodies # Folder where bodies are located
|
||||
#simulations = user-files/simulations # Folder where the bundle's simulations are located
|
||||
#reportsOnly = "" # If set, name of report folder to look for in order to generate its report
|
||||
#binaries = "" # If set, name of the folder where compiles classes are located: Defaults to GATLING_HOME/target.
|
||||
#results = results # Name of the folder where all reports folder are located
|
||||
}
|
||||
}
|
||||
charting {
|
||||
#noReports = false # When set to true, don't generate HTML reports
|
||||
#maxPlotPerSeries = 1000 # Number of points per graph in Gatling reports
|
||||
#useGroupDurationMetric = false # Switch group timings from cumulated response time to group duration.
|
||||
indicators {
|
||||
#lowerBound = 800 # Lower bound for the requests' response time to track in the reports and the console summary
|
||||
#higherBound = 1200 # Higher bound for the requests' response time to track in the reports and the console summary
|
||||
#percentile1 = 50 # Value for the 1st percentile to track in the reports, the console summary and Graphite
|
||||
#percentile2 = 75 # Value for the 2nd percentile to track in the reports, the console summary and Graphite
|
||||
#percentile3 = 95 # Value for the 3rd percentile to track in the reports, the console summary and Graphite
|
||||
#percentile4 = 99 # Value for the 4th percentile to track in the reports, the console summary and Graphite
|
||||
}
|
||||
}
|
||||
http {
|
||||
#fetchedCssCacheMaxCapacity = 200 # Cache size for CSS parsed content, set to 0 to disable
|
||||
#fetchedHtmlCacheMaxCapacity = 200 # Cache size for HTML parsed content, set to 0 to disable
|
||||
#perUserCacheMaxCapacity = 200 # Per virtual user cache size, set to 0 to disable
|
||||
#warmUpUrl = "http://gatling.io" # The URL to use to warm-up the HTTP stack (blank means disabled)
|
||||
#enableGA = true # Very light Google Analytics, please support
|
||||
ssl {
|
||||
keyStore {
|
||||
#type = "" # Type of SSLContext's KeyManagers store
|
||||
#file = "" # Location of SSLContext's KeyManagers store
|
||||
#password = "" # Password for SSLContext's KeyManagers store
|
||||
#algorithm = "" # Algorithm used SSLContext's KeyManagers store
|
||||
}
|
||||
trustStore {
|
||||
#type = "" # Type of SSLContext's TrustManagers store
|
||||
#file = "" # Location of SSLContext's TrustManagers store
|
||||
#password = "" # Password for SSLContext's TrustManagers store
|
||||
#algorithm = "" # Algorithm used by SSLContext's TrustManagers store
|
||||
}
|
||||
}
|
||||
ahc {
|
||||
#keepAlive = true # Allow pooling HTTP connections (keep-alive header automatically added)
|
||||
#connectTimeout = 60000 # Timeout when establishing a connection
|
||||
#pooledConnectionIdleTimeout = 60000 # Timeout when a connection stays unused in the pool
|
||||
#readTimeout = 60000 # Timeout when a used connection stays idle
|
||||
#maxRetry = 2 # Number of times that a request should be tried again
|
||||
#requestTimeout = 60000 # Timeout of the requests
|
||||
#acceptAnyCertificate = true # When set to true, doesn't validate SSL certificates
|
||||
#httpClientCodecMaxInitialLineLength = 4096 # Maximum length of the initial line of the response (e.g. "HTTP/1.0 200 OK")
|
||||
#httpClientCodecMaxHeaderSize = 8192 # Maximum size, in bytes, of each request's headers
|
||||
#httpClientCodecMaxChunkSize = 8192 # Maximum length of the content or each chunk
|
||||
#webSocketMaxFrameSize = 10240000 # Maximum frame payload size
|
||||
#sslEnabledProtocols = [TLSv1.2, TLSv1.1, TLSv1] # Array of enabled protocols for HTTPS, if empty use the JDK defaults
|
||||
#sslEnabledCipherSuites = [] # Array of enabled cipher suites for HTTPS, if empty use the JDK defaults
|
||||
#sslSessionCacheSize = 0 # SSLSession cache size, set to 0 to use JDK's default
|
||||
#sslSessionTimeout = 0 # SSLSession timeout in seconds, set to 0 to use JDK's default (24h)
|
||||
#useOpenSsl = false # if OpenSSL should be used instead of JSSE (requires tcnative jar)
|
||||
#useNativeTransport = false # if native transport should be used instead of Java NIO (requires netty-transport-native-epoll, currently Linux only)
|
||||
#usePooledMemory = true # if Gatling should use pooled memory
|
||||
#tcpNoDelay = true
|
||||
#soReuseAddress = false
|
||||
#soLinger = -1
|
||||
#soSndBuf = -1
|
||||
#soRcvBuf = -1
|
||||
}
|
||||
dns {
|
||||
#queryTimeout = 5000 # Timeout of each DNS query in millis
|
||||
#maxQueriesPerResolve = 3 # Maximum allowed number of DNS queries for a given name resolution
|
||||
}
|
||||
}
|
||||
data {
|
||||
#writers = [console, file] # The list of DataWriters to which Gatling write simulation data (currently supported : console, file, graphite, jdbc)
|
||||
console {
|
||||
#light = false # When set to true, displays a light version without detailed request stats
|
||||
}
|
||||
file {
|
||||
#bufferSize = 8192 # FileDataWriter's internal data buffer size, in bytes
|
||||
}
|
||||
leak {
|
||||
#noActivityTimeout = 30 # Period, in seconds, for which Gatling may have no activity before considering a leak may be happening
|
||||
}
|
||||
graphite {
|
||||
#light = false # only send the all* stats
|
||||
#host = "localhost" # The host where the Carbon server is located
|
||||
#port = 2003 # The port to which the Carbon server listens to (2003 is default for plaintext, 2004 is default for pickle)
|
||||
#protocol = "tcp" # The protocol used to send data to Carbon (currently supported : "tcp", "udp")
|
||||
#rootPathPrefix = "gatling" # The common prefix of all metrics sent to Graphite
|
||||
#bufferSize = 8192 # GraphiteDataWriter's internal data buffer size, in bytes
|
||||
#writeInterval = 1 # GraphiteDataWriter's write interval, in seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
|
||||
<immediateFlush>false</immediateFlush>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Uncomment for logging ALL HTTP request and responses -->
|
||||
<!-- <logger name="io.gatling.http.ahc" level="TRACE" /> -->
|
||||
<!-- <logger name="io.gatling.http.response" level="TRACE" /> -->
|
||||
<!-- Uncomment for logging ONLY FAILED HTTP request and responses -->
|
||||
<!-- <logger name="io.gatling.http.ahc" level="DEBUG" /> -->
|
||||
<!-- <logger name="io.gatling.http.response" level="DEBUG" /> -->
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,53 @@
|
||||
recorder {
|
||||
core {
|
||||
#mode = "Proxy"
|
||||
#encoding = "utf-8" # The encoding used for reading/writing request bodies and the generated simulation
|
||||
#outputFolder = "" # The folder where generated simulation will we written
|
||||
#package = "" # The package's name of the generated simulation
|
||||
#className = "RecordedSimulation" # The name of the generated Simulation class
|
||||
#thresholdForPauseCreation = 100 # The minimum time, in milliseconds, that must pass between requests to trigger a pause creation
|
||||
#saveConfig = false # When set to true, the configuration from the Recorder GUI overwrites this configuration
|
||||
#headless = false # When set to true, run the Recorder in headless mode instead of the GUI
|
||||
#harFilePath = "" # The path of the HAR file to convert
|
||||
}
|
||||
filters {
|
||||
#filterStrategy = "Disabled" # The selected filter resources filter strategy (currently supported : "Disabled", "BlackList", "WhiteList")
|
||||
#whitelist = [] # The list of ressources patterns that are part of the Recorder's whitelist
|
||||
#blacklist = [] # The list of ressources patterns that are part of the Recorder's blacklist
|
||||
}
|
||||
http {
|
||||
#automaticReferer = true # When set to false, write the referer + enable 'disableAutoReferer' in the generated simulation
|
||||
#followRedirect = true # When set to false, write redirect requests + enable 'disableFollowRedirect' in the generated simulation
|
||||
#removeCacheHeaders = true # When set to true, removes from the generated requests headers leading to request caching
|
||||
#inferHtmlResources = true # When set to true, add inferred resources + set 'inferHtmlResources' with the configured blacklist/whitelist in the generated simulation
|
||||
#checkResponseBodies = false # When set to true, save response bodies as files and add raw checks in the generated simulation
|
||||
}
|
||||
proxy {
|
||||
#port = 8000 # Local port used by Gatling's Proxy for HTTP/HTTPS
|
||||
https {
|
||||
#mode = "SelfSignedCertificate" # The selected "HTTPS mode" (currently supported : "SelfSignedCertificate", "ProvidedKeyStore", "GatlingCertificateAuthority", "CustomCertificateAuthority")
|
||||
keyStore {
|
||||
#path = "" # The path of the custom key store
|
||||
#password = "" # The password for this key store
|
||||
#type = "JKS" # The type of the key store (currently supported: "JKS")
|
||||
}
|
||||
certificateAuthority {
|
||||
#certificatePath = "" # The path of the custom certificate
|
||||
#privateKeyPath = "" # The certificate's private key path
|
||||
}
|
||||
}
|
||||
outgoing {
|
||||
#host = "" # The outgoing proxy's hostname
|
||||
#username = "" # The username to use to connect to the outgoing proxy
|
||||
#password = "" # The password corresponding to the user to use to connect to the outgoing proxy
|
||||
#port = 0 # The HTTP port to use to connect to the outgoing proxy
|
||||
#sslPort = 0 # If set, The HTTPS port to use to connect to the outgoing proxy
|
||||
}
|
||||
}
|
||||
netty {
|
||||
#maxInitialLineLength = 10000 # Maximum length of the initial line of the response (e.g. "HTTP/1.0 200 OK")
|
||||
#maxHeaderSize = 20000 # Maximum size, in bytes, of each request's headers
|
||||
#maxChunkSize = 8192 # Maximum length of the content or each chunk
|
||||
#maxContentLength = 100000000 # Maximum length of the aggregated content of each response
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import io.gatling.app.Gatling
|
||||
import io.gatling.core.config.GatlingPropertiesBuilder
|
||||
|
||||
object Engine extends App {
|
||||
|
||||
val props = new GatlingPropertiesBuilder
|
||||
props.dataDirectory(IDEPathHelper.dataDirectory.toString)
|
||||
props.resultsDirectory(IDEPathHelper.resultsDirectory.toString)
|
||||
props.bodiesDirectory(IDEPathHelper.bodiesDirectory.toString)
|
||||
props.binariesDirectory(IDEPathHelper.mavenBinariesDirectory.toString)
|
||||
|
||||
Gatling.fromMap(props.build)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import java.nio.file.Path
|
||||
|
||||
import io.gatling.commons.util.PathHelper._
|
||||
|
||||
object IDEPathHelper {
|
||||
|
||||
val gatlingConfUrl: Path = getClass.getClassLoader.getResource("gatling.conf").toURI
|
||||
val projectRootDir = gatlingConfUrl.ancestor(3)
|
||||
|
||||
val mavenSourcesDirectory = projectRootDir / "src" / "test" / "scala"
|
||||
val mavenResourcesDirectory = projectRootDir / "src" / "test" / "resources"
|
||||
val mavenTargetDirectory = projectRootDir / "target"
|
||||
val mavenBinariesDirectory = mavenTargetDirectory / "test-classes"
|
||||
|
||||
val dataDirectory = mavenResourcesDirectory / "data"
|
||||
val bodiesDirectory = mavenResourcesDirectory / "bodies"
|
||||
|
||||
val recorderOutputDirectory = mavenSourcesDirectory
|
||||
val resultsDirectory = mavenTargetDirectory / "gatling"
|
||||
|
||||
val recorderConfigFile = mavenResourcesDirectory / "recorder.conf"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import io.gatling.recorder.GatlingRecorder
|
||||
import io.gatling.recorder.config.RecorderPropertiesBuilder
|
||||
|
||||
object Recorder extends App {
|
||||
|
||||
val props = new RecorderPropertiesBuilder
|
||||
props.simulationOutputFolder(IDEPathHelper.recorderOutputDirectory.toString)
|
||||
props.simulationPackage("org.baeldung")
|
||||
props.bodiesFolder(IDEPathHelper.bodiesDirectory.toString)
|
||||
|
||||
GatlingRecorder.fromMap(props.build, Some(IDEPathHelper.recorderConfigFile))
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.baeldung
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import io.gatling.core.Predef._
|
||||
import io.gatling.http.Predef._
|
||||
import io.gatling.jdbc.Predef._
|
||||
|
||||
class RecordedSimulation extends Simulation {
|
||||
|
||||
val httpProtocol = http
|
||||
.baseURL("http://computer-database.gatling.io")
|
||||
.inferHtmlResources(BlackList(""".*\.css""", """.*\.js""", """.*\.ico"""), WhiteList())
|
||||
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
|
||||
.acceptEncodingHeader("gzip, deflate")
|
||||
.acceptLanguageHeader("it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3")
|
||||
.userAgentHeader("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
val scn = scenario("RecordedSimulation")
|
||||
.exec(http("request_0")
|
||||
.get("/"))
|
||||
.pause(5)
|
||||
.exec(http("request_1")
|
||||
.get("/computers?f=amstrad"))
|
||||
.pause(4)
|
||||
.exec(http("request_2")
|
||||
.get("/computers/412"))
|
||||
.pause(2)
|
||||
.exec(http("request_3")
|
||||
.get("/"))
|
||||
.pause(2)
|
||||
.exec(http("request_4")
|
||||
.get("/computers?p=1"))
|
||||
.pause(1)
|
||||
.exec(http("request_5")
|
||||
.get("/computers?p=2"))
|
||||
.pause(2)
|
||||
.exec(http("request_6")
|
||||
.get("/computers?p=3"))
|
||||
|
||||
setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
### Relevant articles
|
||||
|
||||
- [Introduction to Testing with Spock and Groovy](http://www.baeldung.com/groovy-spock)
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.spockframework</groupId>
|
||||
<artifactId>groovy-spock</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spock Framework - Example Project</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmavenplus</groupId>
|
||||
<artifactId>gmavenplus-plugin</artifactId>
|
||||
<version>1.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spockframework</groupId>
|
||||
<artifactId>spock-core</artifactId>
|
||||
<version>1.0-groovy-2.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>2.4.7</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,89 @@
|
||||
import spock.lang.Specification
|
||||
|
||||
class FirstSpecification extends Specification {
|
||||
|
||||
def "one plus one should equal two"() {
|
||||
expect:
|
||||
1 + 1 == 2
|
||||
}
|
||||
|
||||
def "two plus two should equal four"() {
|
||||
given:
|
||||
int left = 2
|
||||
int right = 2
|
||||
|
||||
when:
|
||||
int result = left + right
|
||||
|
||||
then:
|
||||
result == 4
|
||||
}
|
||||
|
||||
def "Should be able to remove from list"() {
|
||||
given:
|
||||
def list = [1, 2, 3, 4]
|
||||
|
||||
when:
|
||||
list.remove(0)
|
||||
|
||||
then:
|
||||
list == [2, 3, 4]
|
||||
}
|
||||
|
||||
def "Should get an index out of bounds when removing a non-existent item"() {
|
||||
given:
|
||||
def list = [1, 2, 3, 4]
|
||||
|
||||
when:
|
||||
list.remove(20)
|
||||
|
||||
then:
|
||||
thrown(IndexOutOfBoundsException)
|
||||
list.size() == 4
|
||||
}
|
||||
|
||||
def "numbers to the power of two"(int a, int b, int c) {
|
||||
expect:
|
||||
Math.pow(a, b) == c
|
||||
|
||||
where:
|
||||
a | b | c
|
||||
1 | 2 | 1
|
||||
2 | 2 | 4
|
||||
3 | 2 | 9
|
||||
}
|
||||
|
||||
def "Should return default value for mock"() {
|
||||
given:
|
||||
def paymentGateway = Mock(PaymentGateway)
|
||||
|
||||
when:
|
||||
def result = paymentGateway.makePayment(12.99)
|
||||
|
||||
then:
|
||||
!result
|
||||
}
|
||||
|
||||
def "Should return true value for mock"() {
|
||||
given:
|
||||
def paymentGateway = Mock(PaymentGateway)
|
||||
paymentGateway.makePayment(20) >> true
|
||||
|
||||
when:
|
||||
def result = paymentGateway.makePayment(20)
|
||||
|
||||
then:
|
||||
result
|
||||
}
|
||||
|
||||
def "Should verify notify was called"() {
|
||||
given:
|
||||
def notifier = Mock(Notifier)
|
||||
|
||||
when:
|
||||
notifier.notify('foo')
|
||||
|
||||
then:
|
||||
1 * notifier.notify('foo')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
interface Notifier {
|
||||
void notify(String message)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
interface PaymentGateway {
|
||||
boolean makePayment(BigDecimal amount)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
### Relevant Articles:
|
||||
- [The Basics of JUnit 5 – A Preview](http://www.baeldung.com/junit-5-preview)
|
||||
- [A Guide to JUnit 5](http://www.baeldung.com/junit-5)
|
||||
- [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests)
|
||||
- [A Guide to @RepeatedTest in Junit 5](http://www.baeldung.com/junit-5-repeated-test)
|
||||
- [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests)
|
||||
- [A Guied to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions)
|
||||
- [Inject Parameters into JUnit Jupiter Unit Tests](http://www.baeldung.com/junit-5-parameters)
|
||||
- [Mockito and JUnit 5 – Using ExtendWith](http://www.baeldung.com/mockito-junit-5-extension)
|
||||
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<!-- NOT NEEDED - JSP <groupId>com.baeldung</groupId>-->
|
||||
<artifactId>junit-5</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<name>junit-5</name>
|
||||
<description>Intro to JUnit 5</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<junit.jupiter.version>5.0.1</junit.jupiter.version>
|
||||
<junit.platform.version>1.0.1</junit.platform.version>
|
||||
<junit.vintage.version>4.12.1</junit.vintage.version>
|
||||
<log4j2.version>2.8.2</log4j2.version>
|
||||
<h2.version>1.4.196</h2.version>
|
||||
<mockito.version>2.11.0</mockito.version>
|
||||
|
||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||
<junit4.version>4.12</junit4.version>
|
||||
<spring.version>5.0.1.RELEASE</spring.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/test/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-surefire-provider</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<mainClass>com.baeldung.TestLauncher</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<version>${junit.vintage.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit4.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.junit5.mockito;
|
||||
|
||||
public class User {
|
||||
|
||||
private Integer id;
|
||||
private String name;
|
||||
private int age;
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
|
||||
}
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.junit5.mockito.repository;
|
||||
|
||||
import com.baeldung.junit5.mockito.User;
|
||||
|
||||
public interface MailClient {
|
||||
|
||||
void sendUserRegistrationMail(User user);
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.junit5.mockito.repository;
|
||||
|
||||
public interface SettingRepository {
|
||||
|
||||
int getUserMinAge();
|
||||
|
||||
int getUserNameMinLength();
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.junit5.mockito.repository;
|
||||
|
||||
import com.baeldung.junit5.mockito.User;
|
||||
|
||||
public interface UserRepository {
|
||||
|
||||
User insert(User user);
|
||||
boolean isUsernameAlreadyExists(String userName);
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.junit5.mockito.service;
|
||||
|
||||
import com.baeldung.junit5.mockito.User;
|
||||
import com.baeldung.junit5.mockito.repository.MailClient;
|
||||
import com.baeldung.junit5.mockito.repository.SettingRepository;
|
||||
import com.baeldung.junit5.mockito.repository.UserRepository;
|
||||
|
||||
public class DefaultUserService implements UserService {
|
||||
|
||||
private UserRepository userRepository;
|
||||
private SettingRepository settingRepository;
|
||||
private MailClient mailClient;
|
||||
|
||||
public DefaultUserService(UserRepository userRepository, SettingRepository settingRepository, MailClient mailClient) {
|
||||
this.userRepository = userRepository;
|
||||
this.settingRepository = settingRepository;
|
||||
this.mailClient = mailClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User register(User user) {
|
||||
validate(user);
|
||||
User insertedUser = userRepository.insert(user);
|
||||
mailClient.sendUserRegistrationMail(insertedUser);
|
||||
return insertedUser;
|
||||
}
|
||||
|
||||
private void validate(User user) {
|
||||
if(user.getName() == null) {
|
||||
throw new RuntimeException(Errors.USER_NAME_REQUIRED);
|
||||
}
|
||||
|
||||
if(user.getName().length() < settingRepository.getUserNameMinLength()) {
|
||||
throw new RuntimeException(Errors.USER_NAME_SHORT);
|
||||
}
|
||||
|
||||
if(user.getAge() < settingRepository.getUserMinAge()) {
|
||||
throw new RuntimeException(Errors.USER_AGE_YOUNG);
|
||||
}
|
||||
|
||||
if(userRepository.isUsernameAlreadyExists(user.getName())) {
|
||||
throw new RuntimeException(Errors.USER_NAME_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.junit5.mockito.service;
|
||||
|
||||
public class Errors {
|
||||
|
||||
public static final String USER_NAME_REQUIRED = "user.name.required";
|
||||
public static final String USER_NAME_SHORT = "user.name.short";
|
||||
public static final String USER_AGE_YOUNG = "user.age.young";
|
||||
public static final String USER_NAME_DUPLICATE = "user.name.duplicate";
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.junit5.mockito.service;
|
||||
|
||||
import com.baeldung.junit5.mockito.User;
|
||||
|
||||
public interface UserService {
|
||||
|
||||
User register(User user);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.baeldung;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class AssertionUnitTest {
|
||||
|
||||
@Test
|
||||
public void testConvertToDoubleThrowException() {
|
||||
String age = "eighteen";
|
||||
assertThrows(NumberFormatException.class, () -> {
|
||||
convertToInt(age);
|
||||
});
|
||||
|
||||
assertThrows(NumberFormatException.class, () -> {
|
||||
convertToInt(age);
|
||||
});
|
||||
}
|
||||
|
||||
private static Integer convertToInt(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
return Integer.valueOf(str);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.baeldung;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeFalse;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
import static org.junit.jupiter.api.Assumptions.assumingThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class AssumptionUnitTest {
|
||||
|
||||
@Test
|
||||
void trueAssumption() {
|
||||
assumeTrue(5 > 1);
|
||||
assertEquals(5 + 2, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
void falseAssumption() {
|
||||
assumeFalse(5 < 1);
|
||||
assertEquals(5 + 2, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
void assumptionThat() {
|
||||
String someString = "Just a string";
|
||||
assumingThat(someString.equals("Just a string"), () -> assertEquals(2 + 2, 4));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.baeldung;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.junit.jupiter.api.function.ThrowingConsumer;
|
||||
|
||||
import com.baeldung.helpers.Employee;
|
||||
import com.baeldung.helpers.EmployeeDao;
|
||||
|
||||
public class DynamicTestsExample {
|
||||
|
||||
@TestFactory
|
||||
Collection<DynamicTest> dynamicTestsWithCollection() {
|
||||
return Arrays.asList(DynamicTest.dynamicTest("Add test", () -> assertEquals(2, Math.addExact(1, 1))), DynamicTest.dynamicTest("Multiply Test", () -> assertEquals(4, Math.multiplyExact(2, 2))));
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Iterable<DynamicTest> dynamicTestsWithIterable() {
|
||||
return Arrays.asList(DynamicTest.dynamicTest("Add test", () -> assertEquals(2, Math.addExact(1, 1))), DynamicTest.dynamicTest("Multiply Test", () -> assertEquals(4, Math.multiplyExact(2, 2))));
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Iterator<DynamicTest> dynamicTestsWithIterator() {
|
||||
return Arrays.asList(DynamicTest.dynamicTest("Add test", () -> assertEquals(2, Math.addExact(1, 1))), DynamicTest.dynamicTest("Multiply Test", () -> assertEquals(4, Math.multiplyExact(2, 2))))
|
||||
.iterator();
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest> dynamicTestsFromIntStream() {
|
||||
return IntStream.iterate(0, n -> n + 2)
|
||||
.limit(10)
|
||||
.mapToObj(n -> DynamicTest.dynamicTest("test" + n, () -> assertTrue(n % 2 == 0)));
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest> dynamicTestsFromStream() {
|
||||
|
||||
// sample input and output
|
||||
List<String> inputList = Arrays.asList("www.somedomain.com", "www.anotherdomain.com", "www.yetanotherdomain.com");
|
||||
List<String> outputList = Arrays.asList("154.174.10.56", "211.152.104.132", "178.144.120.156");
|
||||
|
||||
// input generator that generates inputs using inputList
|
||||
Iterator<String> inputGenerator = inputList.iterator();
|
||||
|
||||
// a display name generator that creates a different name based on the input
|
||||
Function<String, String> displayNameGenerator = (input) -> "Resolving: " + input;
|
||||
|
||||
// the test executor, which actually has the logic of how to execute the test case
|
||||
DomainNameResolver resolver = new DomainNameResolver();
|
||||
ThrowingConsumer<String> testExecutor = (input) -> {
|
||||
int id = inputList.indexOf(input);
|
||||
assertEquals(outputList.get(id), resolver.resolveDomain(input));
|
||||
};
|
||||
|
||||
// combine everything and return a Stream of DynamicTest
|
||||
return DynamicTest.stream(inputGenerator, displayNameGenerator, testExecutor);
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest> dynamicTestsFromStreamInJava8() {
|
||||
|
||||
DomainNameResolver resolver = new DomainNameResolver();
|
||||
|
||||
List<String> inputList = Arrays.asList("www.somedomain.com", "www.anotherdomain.com", "www.yetanotherdomain.com");
|
||||
List<String> outputList = Arrays.asList("154.174.10.56", "211.152.104.132", "178.144.120.156");
|
||||
|
||||
return inputList.stream()
|
||||
.map(dom -> DynamicTest.dynamicTest("Resolving: " + dom, () -> {
|
||||
int id = inputList.indexOf(dom);
|
||||
assertEquals(outputList.get(id), resolver.resolveDomain(dom));
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Stream<DynamicTest> dynamicTestsForEmployeeWorkflows() {
|
||||
List<Employee> inputList = Arrays.asList(new Employee(1, "Fred"), new Employee(2), new Employee(3, "John"));
|
||||
|
||||
EmployeeDao dao = new EmployeeDao();
|
||||
Stream<DynamicTest> saveEmployeeStream = inputList.stream()
|
||||
.map(emp -> DynamicTest.dynamicTest("saveEmployee: " + emp.toString(), () -> {
|
||||
Employee returned = dao.save(emp.getId());
|
||||
assertEquals(returned.getId(), emp.getId());
|
||||
}));
|
||||
|
||||
Stream<DynamicTest> saveEmployeeWithFirstNameStream = inputList.stream()
|
||||
.filter(emp -> !emp.getFirstName()
|
||||
.isEmpty())
|
||||
.map(emp -> DynamicTest.dynamicTest("saveEmployeeWithName" + emp.toString(), () -> {
|
||||
Employee returned = dao.save(emp.getId(), emp.getFirstName());
|
||||
assertEquals(returned.getId(), emp.getId());
|
||||
assertEquals(returned.getFirstName(), emp.getFirstName());
|
||||
}));
|
||||
|
||||
return Stream.concat(saveEmployeeStream, saveEmployeeWithFirstNameStream);
|
||||
}
|
||||
|
||||
class DomainNameResolver {
|
||||
|
||||
private Map<String, String> ipByDomainName = new HashMap<>();
|
||||
|
||||
DomainNameResolver() {
|
||||
this.ipByDomainName.put("www.somedomain.com", "154.174.10.56");
|
||||
this.ipByDomainName.put("www.anotherdomain.com", "211.152.104.132");
|
||||
this.ipByDomainName.put("www.yetanotherdomain.com", "178.144.120.156");
|
||||
}
|
||||
|
||||
public String resolveDomain(String domainName) {
|
||||
return ipByDomainName.get(domainName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.baeldung;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import com.baeldung.extensions.EmployeeDaoParameterResolver;
|
||||
import com.baeldung.extensions.EmployeeDatabaseSetupExtension;
|
||||
import com.baeldung.extensions.EnvironmentExtension;
|
||||
import com.baeldung.extensions.IgnoreFileNotFoundExceptionExtension;
|
||||
import com.baeldung.extensions.LoggingExtension;
|
||||
import com.baeldung.helpers.Employee;
|
||||
import com.baeldung.helpers.EmployeeJdbcDao;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ExtendWith({ EnvironmentExtension.class, EmployeeDatabaseSetupExtension.class, EmployeeDaoParameterResolver.class })
|
||||
@ExtendWith(LoggingExtension.class)
|
||||
@ExtendWith(IgnoreFileNotFoundExceptionExtension.class)
|
||||
public class EmployeesTest {
|
||||
|
||||
private EmployeeJdbcDao employeeDao;
|
||||
|
||||
private Logger logger;
|
||||
|
||||
public EmployeesTest(EmployeeJdbcDao employeeDao) {
|
||||
this.employeeDao = employeeDao;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddEmployee_thenGetEmployee() throws SQLException {
|
||||
Employee emp = new Employee(1, "john");
|
||||
employeeDao.add(emp);
|
||||
assertEquals(1, employeeDao.findAll()
|
||||
.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetEmployees_thenEmptyList() throws SQLException {
|
||||
assertEquals(0, employeeDao.findAll()
|
||||
.size());
|
||||
}
|
||||
|
||||
public void setLogger(Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.baeldung;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ExceptionUnitTest {
|
||||
|
||||
@Test
|
||||
void shouldThrowException() {
|
||||
Throwable exception = assertThrows(UnsupportedOperationException.class, () -> {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
});
|
||||
assertEquals(exception.getMessage(), "Not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
void assertThrowsException() {
|
||||
String str = null;
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
Integer.valueOf(str);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baeldung;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class FirstUnitTest {
|
||||
|
||||
@Test
|
||||
void lambdaExpressions() {
|
||||
List<Integer> numbers = Arrays.asList(1, 2, 3);
|
||||
assertTrue(numbers.stream()
|
||||
.mapToInt(i -> i)
|
||||
.sum() > 5, "Sum should be greater than 5");
|
||||
}
|
||||
|
||||
@Disabled("test to show MultipleFailuresError")
|
||||
@Test
|
||||
void groupAssertions() {
|
||||
int[] numbers = { 0, 1, 2, 3, 4 };
|
||||
assertAll("numbers", () -> assertEquals(numbers[0], 1), () -> assertEquals(numbers[3], 3), () -> assertEquals(numbers[4], 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
void disabledTest() {
|
||||
assertTrue(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.baeldung;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
//@RunWith(JUnitPlatform.class)
|
||||
public class JUnit5NewFeaturesUnitTest {
|
||||
|
||||
private static final Logger log = Logger.getLogger(JUnit5NewFeaturesUnitTest.class.getName());
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
log.info("@BeforeAll - executes once before all test methods in this class");
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
log.info("@BeforeEach - executes before each test method in this class");
|
||||
}
|
||||
|
||||
@DisplayName("Single test successful")
|
||||
@Test
|
||||
void testSingleSuccessTest() {
|
||||
log.info("Success");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("Not implemented yet.")
|
||||
void testShowSomething() {
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
log.info("@AfterEach - executed after each test method.");
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void done() {
|
||||
log.info("@AfterAll - executed after all test methods.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.baeldung;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
|
||||
public class LiveTest {
|
||||
|
||||
private List<String> in = new ArrayList<>(Arrays.asList("Hello", "Yes", "No"));
|
||||
private List<String> out = new ArrayList<>(Arrays.asList("Cześć", "Tak", "Nie"));
|
||||
|
||||
@TestFactory
|
||||
public Stream<DynamicTest> translateDynamicTestsFromStream() {
|
||||
|
||||
return in.stream()
|
||||
.map(word -> DynamicTest.dynamicTest("Test translate " + word, () -> {
|
||||
int id = in.indexOf(word);
|
||||
assertEquals(out.get(id), translate(word));
|
||||
}));
|
||||
}
|
||||
|
||||
private String translate(String word) {
|
||||
if ("Hello".equalsIgnoreCase(word)) {
|
||||
return "Cześć";
|
||||
} else if ("Yes".equalsIgnoreCase(word)) {
|
||||
return "Tak";
|
||||
} else if ("No".equalsIgnoreCase(word)) {
|
||||
return "Nie";
|
||||
}
|
||||
return "Error";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.baeldung;
|
||||
|
||||
import java.util.EmptyStackException;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class NestedUnitTest {
|
||||
Stack<Object> stack;
|
||||
boolean isRun = false;
|
||||
|
||||
@Test
|
||||
@DisplayName("is instantiated with new Stack()")
|
||||
void isInstantiatedWithNew() {
|
||||
new Stack<Object>();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("when new")
|
||||
class WhenNew {
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
stack = new Stack<Object>();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("is empty")
|
||||
void isEmpty() {
|
||||
Assertions.assertTrue(stack.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("throws EmptyStackException when popped")
|
||||
void throwsExceptionWhenPopped() {
|
||||
Assertions.assertThrows(EmptyStackException.class, () -> stack.pop());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("throws EmptyStackException when peeked")
|
||||
void throwsExceptionWhenPeeked() {
|
||||
Assertions.assertThrows(EmptyStackException.class, () -> stack.peek());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("after pushing an element")
|
||||
class AfterPushing {
|
||||
|
||||
String anElement = "an element";
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
stack.push(anElement);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("it is no longer empty")
|
||||
void isEmpty() {
|
||||
Assertions.assertFalse(stack.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("returns the element when popped and is empty")
|
||||
void returnElementWhenPopped() {
|
||||
Assertions.assertEquals(anElement, stack.pop());
|
||||
Assertions.assertTrue(stack.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("returns the element when peeked but remains not empty")
|
||||
void returnElementWhenPeeked() {
|
||||
Assertions.assertEquals(anElement, stack.peek());
|
||||
Assertions.assertFalse(stack.isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.baeldung;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.RepetitionInfo;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
|
||||
public class RepeatedTestExample {
|
||||
|
||||
@BeforeEach
|
||||
void beforeEachTest() {
|
||||
System.out.println("Before Each Test");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEachTest() {
|
||||
System.out.println("After Each Test");
|
||||
System.out.println("=====================");
|
||||
}
|
||||
|
||||
@RepeatedTest(3)
|
||||
void repeatedTest(TestInfo testInfo) {
|
||||
System.out.println("Executing repeated test");
|
||||
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
|
||||
}
|
||||
|
||||
@RepeatedTest(value = 3, name = RepeatedTest.LONG_DISPLAY_NAME)
|
||||
void repeatedTestWithLongName() {
|
||||
System.out.println("Executing repeated test with long name");
|
||||
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
|
||||
}
|
||||
|
||||
@RepeatedTest(value = 3, name = RepeatedTest.SHORT_DISPLAY_NAME)
|
||||
void repeatedTestWithShortName() {
|
||||
System.out.println("Executing repeated test with long name");
|
||||
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
|
||||
}
|
||||
|
||||
@RepeatedTest(value = 3, name = "Custom name {currentRepetition}/{totalRepetitions}")
|
||||
void repeatedTestWithCustomDisplayName() {
|
||||
assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2");
|
||||
}
|
||||
|
||||
@RepeatedTest(3)
|
||||
void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
|
||||
System.out.println("Repetition #" + repetitionInfo.getCurrentRepetition());
|
||||
assertEquals(3, repetitionInfo.getTotalRepetitions());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung;
|
||||
|
||||
public final class StringUtils {
|
||||
|
||||
public static Double convertToDouble(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
return Double.valueOf(str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.baeldung;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Tag("Test case")
|
||||
public class TaggedUnitTest {
|
||||
|
||||
@Test
|
||||
@Tag("Method")
|
||||
void testMethod() {
|
||||
assertEquals(2 + 2, 4);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.junit.platform.launcher.LauncherDiscoveryRequest;
|
||||
import org.junit.platform.launcher.TestExecutionListener;
|
||||
import org.junit.platform.launcher.TestPlan;
|
||||
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
|
||||
import org.junit.platform.launcher.core.LauncherFactory;
|
||||
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
|
||||
|
||||
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import org.junit.platform.launcher.Launcher;
|
||||
|
||||
public class TestLauncher {
|
||||
public static void main(String[] args) {
|
||||
|
||||
//@formatter:off
|
||||
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
|
||||
.selectors(selectClass("com.baeldung.EmployeesTest"))
|
||||
.configurationParameter("junit.conditions.deactivate", "com.baeldung.extensions.*")
|
||||
.configurationParameter("junit.extensions.autodetection.enabled", "true")
|
||||
.build();
|
||||
|
||||
//@formatter:on
|
||||
|
||||
TestPlan plan = LauncherFactory.create()
|
||||
.discover(request);
|
||||
Launcher launcher = LauncherFactory.create();
|
||||
SummaryGeneratingListener summaryGeneratingListener = new SummaryGeneratingListener();
|
||||
launcher.execute(request, new TestExecutionListener[] { summaryGeneratingListener });
|
||||
launcher.execute(request);
|
||||
|
||||
summaryGeneratingListener.getSummary()
|
||||
.printTo(new PrintWriter(System.out));
|
||||
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.extensions;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
|
||||
import com.baeldung.helpers.EmployeeJdbcDao;
|
||||
import com.baeldung.helpers.JdbcConnectionUtil;
|
||||
|
||||
public class EmployeeDaoParameterResolver implements ParameterResolver {
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
|
||||
return parameterContext.getParameter()
|
||||
.getType()
|
||||
.equals(EmployeeJdbcDao.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
|
||||
return new EmployeeJdbcDao(JdbcConnectionUtil.getConnection());
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.extensions;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Savepoint;
|
||||
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
import com.baeldung.helpers.EmployeeJdbcDao;
|
||||
import com.baeldung.helpers.JdbcConnectionUtil;
|
||||
|
||||
public class EmployeeDatabaseSetupExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback {
|
||||
|
||||
private Connection con = JdbcConnectionUtil.getConnection();
|
||||
private EmployeeJdbcDao employeeDao = new EmployeeJdbcDao(con);
|
||||
private Savepoint savepoint;
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) throws SQLException {
|
||||
if (con != null) {
|
||||
con.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) throws SQLException {
|
||||
employeeDao.createTable();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterEach(ExtensionContext context) throws SQLException {
|
||||
con.rollback(savepoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) throws SQLException {
|
||||
con.setAutoCommit(false);
|
||||
savepoint = con.setSavepoint("before");
|
||||
}
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.extensions;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
|
||||
import org.junit.jupiter.api.extension.ExecutionCondition;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
public class EnvironmentExtension implements ExecutionCondition {
|
||||
|
||||
@Override
|
||||
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
|
||||
Properties props = new Properties();
|
||||
|
||||
try {
|
||||
props.load(EnvironmentExtension.class.getResourceAsStream("application.properties"));
|
||||
String env = props.getProperty("env");
|
||||
if ("qa".equalsIgnoreCase(env)) {
|
||||
return ConditionEvaluationResult.disabled("Test disabled on QA environment");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ConditionEvaluationResult.enabled("Test enabled on QA environment");
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.extensions;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
|
||||
|
||||
public class IgnoreFileNotFoundExceptionExtension implements TestExecutionExceptionHandler {
|
||||
|
||||
Logger logger = LogManager.getLogger(IgnoreFileNotFoundExceptionExtension.class);
|
||||
|
||||
@Override
|
||||
public void handleTestExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
|
||||
|
||||
if (throwable instanceof FileNotFoundException) {
|
||||
logger.error("File not found:" + throwable.getMessage());
|
||||
return;
|
||||
}
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.extensions;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||
|
||||
public class LoggingExtension implements TestInstancePostProcessor {
|
||||
|
||||
@Override
|
||||
public void postProcessTestInstance(Object testInstance, ExtensionContext context) throws Exception {
|
||||
Logger logger = LogManager.getLogger(testInstance.getClass());
|
||||
testInstance.getClass()
|
||||
.getMethod("setLogger", Logger.class)
|
||||
.invoke(testInstance, logger);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.helpers;
|
||||
|
||||
public class Employee {
|
||||
|
||||
private long id;
|
||||
private String firstName;
|
||||
|
||||
public Employee(long id) {
|
||||
this.id = id;
|
||||
this.firstName = "";
|
||||
}
|
||||
|
||||
public Employee(long id, String firstName) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Employee [id=" + id + ", firstName=" + firstName + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.helpers;
|
||||
|
||||
public class EmployeeDao {
|
||||
|
||||
public Employee save(long id) {
|
||||
return new Employee(id);
|
||||
}
|
||||
|
||||
public Employee save(long id, String firstName) {
|
||||
return new Employee(id, firstName);
|
||||
}
|
||||
|
||||
public Employee update(Employee employee) {
|
||||
return employee;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.helpers;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class EmployeeJdbcDao {
|
||||
|
||||
private Connection con;
|
||||
|
||||
public EmployeeJdbcDao(Connection con) {
|
||||
this.con = con;
|
||||
}
|
||||
|
||||
public void createTable() throws SQLException {
|
||||
String createQuery = "CREATE TABLE employees(id long primary key, firstName varchar(50))";
|
||||
PreparedStatement pstmt = con.prepareStatement(createQuery);
|
||||
|
||||
pstmt.execute();
|
||||
}
|
||||
|
||||
public void add(Employee emp) throws SQLException {
|
||||
String insertQuery = "INSERT INTO employees(id, firstName) VALUES(?,?)";
|
||||
PreparedStatement pstmt = con.prepareStatement(insertQuery);
|
||||
pstmt.setLong(1, emp.getId());
|
||||
pstmt.setString(2, emp.getFirstName());
|
||||
|
||||
pstmt.executeUpdate();
|
||||
|
||||
}
|
||||
|
||||
public List<Employee> findAll() throws SQLException {
|
||||
List<Employee> employees = new ArrayList<>();
|
||||
String query = "SELECT * FROM employees";
|
||||
PreparedStatement pstmt = con.prepareStatement(query);
|
||||
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
Employee emp = new Employee(rs.getLong("id"), rs.getString("firstName"));
|
||||
employees.add(emp);
|
||||
}
|
||||
|
||||
return employees;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.helpers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
|
||||
public class JdbcConnectionUtil {
|
||||
|
||||
private static Connection con;
|
||||
|
||||
public static Connection getConnection() {
|
||||
if (con == null) {
|
||||
try {
|
||||
Properties props = new Properties();
|
||||
props.load(JdbcConnectionUtil.class.getResourceAsStream("jdbc.properties"));
|
||||
Class.forName(props.getProperty("jdbc.driver"));
|
||||
con = DriverManager.getConnection(props.getProperty("jdbc.url"), props.getProperty("jdbc.user"), props.getProperty("jdbc.password"));
|
||||
return con;
|
||||
} catch (IOException exc) {
|
||||
exc.printStackTrace();
|
||||
} catch (ClassNotFoundException exc) {
|
||||
exc.printStackTrace();
|
||||
} catch (SQLException exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return con;
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials are
|
||||
* made available under the terms of the Eclipse Public License v1.0 which
|
||||
* accompanies this distribution and is available at
|
||||
*
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
|
||||
package com.baeldung.junit5.mockito;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Mock;
|
||||
|
||||
/**
|
||||
* {@code MockitoExtension} showcases the {@link TestInstancePostProcessor}
|
||||
* and {@link ParameterResolver} extension APIs of JUnit 5 by providing
|
||||
* dependency injection support at the field level and at the method parameter
|
||||
* level via Mockito 2.x's {@link Mock @Mock} annotation.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public class MockitoExtension implements TestInstancePostProcessor, ParameterResolver {
|
||||
|
||||
@Override
|
||||
public void postProcessTestInstance(Object testInstance, ExtensionContext context) {
|
||||
MockitoAnnotations.initMocks(testInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
|
||||
return parameterContext.getParameter().isAnnotationPresent(Mock.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
|
||||
return getMock(parameterContext.getParameter(), extensionContext);
|
||||
}
|
||||
|
||||
private Object getMock(Parameter parameter, ExtensionContext extensionContext) {
|
||||
Class<?> mockType = parameter.getType();
|
||||
Store mocks = extensionContext.getStore(Namespace.create(MockitoExtension.class, mockType));
|
||||
String mockName = getMockName(parameter);
|
||||
|
||||
if (mockName != null) {
|
||||
return mocks.getOrComputeIfAbsent(mockName, key -> mock(mockType, mockName));
|
||||
}
|
||||
else {
|
||||
return mocks.getOrComputeIfAbsent(mockType.getCanonicalName(), key -> mock(mockType));
|
||||
}
|
||||
}
|
||||
|
||||
private String getMockName(Parameter parameter) {
|
||||
String explicitMockName = parameter.getAnnotation(Mock.class).name().trim();
|
||||
if (!explicitMockName.isEmpty()) {
|
||||
return explicitMockName;
|
||||
}
|
||||
else if (parameter.isNamePresent()) {
|
||||
return parameter.getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
package com.baeldung.junit5.mockito;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.platform.runner.JUnitPlatform;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import com.baeldung.junit5.mockito.repository.MailClient;
|
||||
import com.baeldung.junit5.mockito.repository.SettingRepository;
|
||||
import com.baeldung.junit5.mockito.repository.UserRepository;
|
||||
import com.baeldung.junit5.mockito.service.DefaultUserService;
|
||||
import com.baeldung.junit5.mockito.service.Errors;
|
||||
import com.baeldung.junit5.mockito.service.UserService;
|
||||
|
||||
@RunWith(JUnitPlatform.class)
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class UserServiceUnitTest {
|
||||
|
||||
UserService userService;
|
||||
@Mock UserRepository userRepository;
|
||||
|
||||
User user;
|
||||
|
||||
@BeforeEach
|
||||
void init(@Mock SettingRepository settingRepository, @Mock MailClient mailClient) {
|
||||
userService = new DefaultUserService(userRepository, settingRepository, mailClient);
|
||||
when(settingRepository.getUserMinAge()).thenReturn(10);
|
||||
when(settingRepository.getUserNameMinLength()).thenReturn(4);
|
||||
when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenValidUser_whenSaveUser_thenSucceed(@Mock MailClient mailClient) {
|
||||
// Given
|
||||
user = new User("Jerry", 12);
|
||||
when(userRepository.insert(any(User.class))).then(new Answer<User>() {
|
||||
int sequence = 1;
|
||||
|
||||
@Override
|
||||
public User answer(InvocationOnMock invocation) throws Throwable {
|
||||
User user = (User) invocation.getArgument(0);
|
||||
user.setId(sequence++);
|
||||
return user;
|
||||
}
|
||||
});
|
||||
|
||||
// When
|
||||
User insertedUser = userService.register(user);
|
||||
|
||||
// Then
|
||||
verify(userRepository).insert(user);
|
||||
Assertions.assertNotNull(user.getId());
|
||||
verify(mailClient).sendUserRegistrationMail(insertedUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenShortName_whenSaveUser_thenGiveShortUsernameError() {
|
||||
// Given
|
||||
user = new User("tom", 12);
|
||||
|
||||
// When
|
||||
try {
|
||||
userService.register(user);
|
||||
fail("Should give an error");
|
||||
} catch(Exception ex) {
|
||||
assertEquals(ex.getMessage(), Errors.USER_NAME_SHORT);
|
||||
}
|
||||
|
||||
// Then
|
||||
verify(userRepository, never()).insert(user);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSmallAge_whenSaveUser_thenGiveYoungUserError() {
|
||||
// Given
|
||||
user = new User("jerry", 3);
|
||||
|
||||
// When
|
||||
try {
|
||||
userService.register(user);
|
||||
fail("Should give an error");
|
||||
} catch(Exception ex) {
|
||||
assertEquals(ex.getMessage(), Errors.USER_AGE_YOUNG);
|
||||
}
|
||||
|
||||
// Then
|
||||
verify(userRepository, never()).insert(user);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenUserWithExistingName_whenSaveUser_thenGiveUsernameAlreadyExistsError() {
|
||||
// Given
|
||||
user = new User("jerry", 12);
|
||||
Mockito.reset(userRepository);
|
||||
when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(true);
|
||||
|
||||
// When
|
||||
try {
|
||||
userService.register(user);
|
||||
fail("Should give an error");
|
||||
} catch(Exception ex) {
|
||||
assertEquals(ex.getMessage(), Errors.USER_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
// Then
|
||||
verify(userRepository, never()).insert(user);
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.migration.junit4;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
import com.baeldung.migration.junit4.categories.Annotations;
|
||||
import com.baeldung.migration.junit4.categories.JUnit4Tests;
|
||||
|
||||
@Category(value = { Annotations.class, JUnit4Tests.class })
|
||||
public class AnnotationTestExampleTest {
|
||||
@Test(expected = Exception.class)
|
||||
public void shouldRaiseAnException() throws Exception {
|
||||
throw new Exception("This is my expected exception");
|
||||
}
|
||||
|
||||
@Test(timeout = 1)
|
||||
@Ignore
|
||||
public void shouldFailBecauseTimeout() throws InterruptedException {
|
||||
Thread.sleep(10);
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.migration.junit4;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class AssertionsExampleTest {
|
||||
@Test
|
||||
@Ignore
|
||||
public void shouldFailBecauseTheNumbersAreNotEqualld() {
|
||||
assertEquals("Numbers are not equal!", 2, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAssertAllTheGroup() {
|
||||
List<Integer> list = Arrays.asList(1, 2, 3);
|
||||
assertEquals("List is not incremental", list.get(0)
|
||||
.intValue(), 1);
|
||||
assertEquals("List is not incremental", list.get(1)
|
||||
.intValue(), 2);
|
||||
assertEquals("List is not incremental", list.get(2)
|
||||
.intValue(), 3);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.migration.junit4;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.migration.junit4.rules.TraceUnitTestRule;
|
||||
|
||||
public class RuleExampleTest {
|
||||
|
||||
@Rule
|
||||
public final TraceUnitTestRule traceRuleTests = new TraceUnitTestRule();
|
||||
|
||||
@Test
|
||||
public void whenTracingTests() {
|
||||
System.out.println("This is my test");
|
||||
/*...*/
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.baeldung.migration.junit4.categories;
|
||||
|
||||
public interface Annotations {
|
||||
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.baeldung.migration.junit4.categories;
|
||||
|
||||
public interface JUnit4Tests {
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.migration.junit4.rules;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.MultipleFailureException;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
public class TraceUnitTestRule implements TestRule {
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
|
||||
return new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
List<Throwable> errors = new ArrayList<Throwable>();
|
||||
|
||||
System.out.println("Starting test ... " + description.getMethodName());
|
||||
try {
|
||||
base.evaluate();
|
||||
} catch (Throwable e) {
|
||||
errors.add(e);
|
||||
} finally {
|
||||
System.out.println("... test finished. " + description.getMethodName());
|
||||
}
|
||||
|
||||
MultipleFailureException.assertEmpty(errors);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.migration.junit5;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.platform.runner.JUnitPlatform;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@Tag("annotations")
|
||||
@Tag("junit5")
|
||||
@RunWith(JUnitPlatform.class)
|
||||
public class AnnotationTestExampleTest {
|
||||
@Test
|
||||
public void shouldRaiseAnException() throws Exception {
|
||||
Assertions.assertThrows(Exception.class, () -> {
|
||||
throw new Exception("This is my expected exception");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void shouldFailBecauseTimeout() throws InterruptedException {
|
||||
Assertions.assertTimeout(Duration.ofMillis(1), () -> Thread.sleep(10));
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.migration.junit5;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.platform.runner.JUnitPlatform;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(JUnitPlatform.class)
|
||||
public class AssertionsExampleTest {
|
||||
@Test
|
||||
@Disabled
|
||||
public void shouldFailBecauseTheNumbersAreNotEqual() {
|
||||
Assertions.assertEquals(2, 3, "Numbers are not equal!");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void shouldFailBecauseItsNotTrue_overloading() {
|
||||
Assertions.assertTrue(() -> {
|
||||
return false;
|
||||
}, () -> "It's not true!");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAssertAllTheGroup() {
|
||||
List<Integer> list = Arrays.asList(1, 2, 3);
|
||||
|
||||
Assertions.assertAll("List is not incremental", () -> Assertions.assertEquals(list.get(0)
|
||||
.intValue(), 1), () -> Assertions.assertEquals(
|
||||
list.get(1)
|
||||
.intValue(),
|
||||
2),
|
||||
() -> Assertions.assertEquals(list.get(2)
|
||||
.intValue(), 3));
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.migration.junit5;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.platform.runner.JUnitPlatform;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import com.baeldung.migration.junit5.extensions.TraceUnitExtension;
|
||||
|
||||
@RunWith(JUnitPlatform.class)
|
||||
@ExtendWith(TraceUnitExtension.class)
|
||||
public class RuleExampleTest {
|
||||
|
||||
@Test
|
||||
public void whenTracingTests() {
|
||||
System.out.println("This is my test");
|
||||
/*...*/
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.migration.junit5.extensions;
|
||||
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
public class TraceUnitExtension implements AfterEachCallback, BeforeEachCallback {
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) throws Exception {
|
||||
System.out.println("Starting test ... " + context.getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterEach(ExtensionContext context) throws Exception {
|
||||
System.out.println("... test finished. " + context.getDisplayName());
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.baeldung.param;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
|
||||
public class InvalidPersonParameterResolver implements ParameterResolver {
|
||||
|
||||
/**
|
||||
* The "bad" (invalid) data for testing purposes has to go somewhere, right?
|
||||
*/
|
||||
public static Person[] INVALID_PERSONS = { new Person().setId(1L)
|
||||
.setLastName("Ad_ams")
|
||||
.setFirstName("Jill,"),
|
||||
new Person().setId(2L)
|
||||
.setLastName(",Baker")
|
||||
.setFirstName(""),
|
||||
new Person().setId(3L)
|
||||
.setLastName(null)
|
||||
.setFirstName(null),
|
||||
new Person().setId(4L)
|
||||
.setLastName("Daniel&")
|
||||
.setFirstName("{Joseph}"),
|
||||
new Person().setId(5L)
|
||||
.setLastName("")
|
||||
.setFirstName("English, Jane"),
|
||||
new Person()/* .setId(6L).setLastName("Fontana").setFirstName("Enrique") */,
|
||||
// TODO: ADD MORE DATA HERE
|
||||
};
|
||||
|
||||
@Override
|
||||
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
|
||||
Object ret = null;
|
||||
//
|
||||
// Return a random, valid Person object if Person.class is the type of Parameter
|
||||
/// to be resolved. Otherwise return null.
|
||||
if (parameterContext.getParameter()
|
||||
.getType() == Person.class) {
|
||||
ret = INVALID_PERSONS[new Random().nextInt(INVALID_PERSONS.length)];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
|
||||
boolean ret = false;
|
||||
//
|
||||
// If the Parameter.type == Person.class, then we support it, otherwise, get outta here!
|
||||
if (parameterContext.getParameter()
|
||||
.getType() == Person.class) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.param;
|
||||
|
||||
/**
|
||||
* Very simple Person entity.
|
||||
* Use the Fluent-style interface to set properties.
|
||||
*
|
||||
* @author J Steven Perry
|
||||
*
|
||||
*/
|
||||
public class Person {
|
||||
|
||||
private Long id;
|
||||
private String lastName;
|
||||
private String firstName;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Person setId(Long id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public Person setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public Person setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.baeldung.param;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Somewhat contrived validation class to illustrate unit test
|
||||
* concepts.
|
||||
*
|
||||
* @author J Steven Perry
|
||||
*
|
||||
*/
|
||||
public class PersonValidator {
|
||||
|
||||
/**
|
||||
* Contrived checked exception to illustrate one possible
|
||||
* way to handle validation errors (via a checked exception).
|
||||
*
|
||||
* @author J Steven Perry
|
||||
*
|
||||
*/
|
||||
public static class ValidationException extends Exception {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -134518049431883102L;
|
||||
|
||||
// Probably should implement some more constructors, but don't want
|
||||
/// to tarnish the lesson...
|
||||
|
||||
/**
|
||||
* The one and only way to create this checked exception.
|
||||
*
|
||||
* @param message
|
||||
* The message accompanying the exception. Should be meaningful.
|
||||
*/
|
||||
public ValidationException(String message) {
|
||||
super(message);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final String[] ILLEGAL_NAME_CHARACTERS = { ",", "_", "{", "}", "!" };
|
||||
|
||||
/**
|
||||
* Validate the first name of the specified Person object.
|
||||
*
|
||||
* @param person
|
||||
* The Person object to validate.
|
||||
*
|
||||
* @return - returns true if the specified Person is valid
|
||||
*
|
||||
* @throws ValidationException
|
||||
* - this Exception is thrown if any kind of validation error occurs.
|
||||
*/
|
||||
public static boolean validateFirstName(Person person) throws ValidationException {
|
||||
boolean ret = true;
|
||||
// The validation rules go here.
|
||||
// Naive: use simple ifs
|
||||
if (person == null) {
|
||||
throw new ValidationException("Person is null (not allowed)!");
|
||||
}
|
||||
if (person.getFirstName() == null) {
|
||||
throw new ValidationException("Person FirstName is null (not allowed)!");
|
||||
}
|
||||
if (person.getFirstName()
|
||||
.isEmpty()) {
|
||||
throw new ValidationException("Person FirstName is an empty String (not allowed)!");
|
||||
}
|
||||
if (!isStringValid(person.getFirstName(), ILLEGAL_NAME_CHARACTERS)) {
|
||||
throw new ValidationException("Person FirstName (" + person.getFirstName() + ") may not contain any of the following characters: " + Arrays.toString(ILLEGAL_NAME_CHARACTERS) + "!");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the last name of the specified Person object. Looks the same as first
|
||||
* name? Look closer. Just kidding. It's the same. But real world code can (and will) diverge.
|
||||
*
|
||||
* @param person
|
||||
* The Person object to validate.
|
||||
*
|
||||
* @return - returns true if the specified Person is valid
|
||||
*
|
||||
* @throws ValidationException
|
||||
* - this Exception is thrown if any kind of validation error occurs.
|
||||
*/
|
||||
public static boolean validateLastName(Person person) throws ValidationException {
|
||||
boolean ret = true;
|
||||
// The validation rules go here.
|
||||
// Naive: use simple ifs
|
||||
if (person == null) {
|
||||
throw new ValidationException("Person is null (not allowed)!");
|
||||
}
|
||||
if (person.getFirstName() == null) {
|
||||
throw new ValidationException("Person FirstName is null (not allowed)!");
|
||||
}
|
||||
if (person.getFirstName()
|
||||
.isEmpty()) {
|
||||
throw new ValidationException("Person FirstName is an empty String (not allowed)!");
|
||||
}
|
||||
if (!isStringValid(person.getFirstName(), ILLEGAL_NAME_CHARACTERS)) {
|
||||
throw new ValidationException("Person LastName (" + person.getLastName() + ") may not contain any of the following characters: " + Arrays.toString(ILLEGAL_NAME_CHARACTERS) + "!");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the specified name. If it contains any of the illegalCharacters,
|
||||
* this method returns false (indicating the name is illegal). Otherwise it returns true.
|
||||
*
|
||||
* @param candidate
|
||||
* The candidate String to validate
|
||||
*
|
||||
* @param illegalCharacters
|
||||
* The characters the String is not allowed to have
|
||||
*
|
||||
* @return - boolean - true if the name is valid, false otherwise.
|
||||
*/
|
||||
private static boolean isStringValid(String candidate, String[] illegalCharacters) {
|
||||
boolean ret = true;
|
||||
for (String illegalChar : illegalCharacters) {
|
||||
if (candidate.contains(illegalChar)) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.baeldung.param;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.platform.runner.JUnitPlatform;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(JUnitPlatform.class)
|
||||
@DisplayName("Testing PersonValidator")
|
||||
public class PersonValidatorTest {
|
||||
|
||||
/**
|
||||
* Nested class, uses ExtendWith
|
||||
* {@link com.baeldung.param.ValidPersonParameterResolver ValidPersonParameterResolver}
|
||||
* to feed Test methods with "good" data.
|
||||
*/
|
||||
@Nested
|
||||
@DisplayName("When using Valid data")
|
||||
@ExtendWith(ValidPersonParameterResolver.class)
|
||||
public class ValidData {
|
||||
|
||||
/**
|
||||
* Repeat the test ten times, that way we have a good shot at
|
||||
* running all of the data through at least once.
|
||||
*
|
||||
* @param person
|
||||
* A valid Person object to validate.
|
||||
*/
|
||||
@RepeatedTest(value = 10)
|
||||
@DisplayName("All first names are valid")
|
||||
public void validateFirstName(Person person) {
|
||||
try {
|
||||
assertTrue(PersonValidator.validateFirstName(person));
|
||||
} catch (PersonValidator.ValidationException e) {
|
||||
fail("Exception not expected: " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeat the test ten times, that way we have a good shot at
|
||||
* running all of the data through at least once.
|
||||
*
|
||||
* @param person
|
||||
* A valid Person object to validate.
|
||||
*/
|
||||
@RepeatedTest(value = 10)
|
||||
@DisplayName("All last names are valid")
|
||||
public void validateLastName(Person person) {
|
||||
try {
|
||||
assertTrue(PersonValidator.validateLastName(person));
|
||||
} catch (PersonValidator.ValidationException e) {
|
||||
fail("Exception not expected: " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested class, uses ExtendWith
|
||||
* {@link com.baeldung.param.InvalidPersonParameterResolver InvalidPersonParameterResolver}
|
||||
* to feed Test methods with "bad" data.
|
||||
*/
|
||||
@Nested
|
||||
@DisplayName("When using Invalid data")
|
||||
@ExtendWith(InvalidPersonParameterResolver.class)
|
||||
public class InvalidData {
|
||||
|
||||
/**
|
||||
* Repeat the test ten times, that way we have a good shot at
|
||||
* running all of the data through at least once.
|
||||
*
|
||||
* @param person
|
||||
* An invalid Person object to validate.
|
||||
*/
|
||||
@RepeatedTest(value = 10)
|
||||
@DisplayName("All first names are invalid")
|
||||
public void validateFirstName(Person person) {
|
||||
assertThrows(PersonValidator.ValidationException.class, () -> PersonValidator.validateFirstName(person));
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeat the test ten times, that way we have a good shot at
|
||||
* running all of the data through at least once.
|
||||
*
|
||||
* @param person
|
||||
* An invalid Person object to validate.
|
||||
*/
|
||||
@RepeatedTest(value = 10)
|
||||
@DisplayName("All first names are invalid")
|
||||
public void validateLastName(Person person) {
|
||||
assertThrows(PersonValidator.ValidationException.class, () -> PersonValidator.validateLastName(person));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.baeldung.param;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
|
||||
public class ValidPersonParameterResolver implements ParameterResolver {
|
||||
|
||||
/**
|
||||
* The "good" (valid) data for testing purposes has to go somewhere, right?
|
||||
*/
|
||||
public static Person[] VALID_PERSONS = { new Person().setId(1L)
|
||||
.setLastName("Adams")
|
||||
.setFirstName("Jill"),
|
||||
new Person().setId(2L)
|
||||
.setLastName("Baker")
|
||||
.setFirstName("James"),
|
||||
new Person().setId(3L)
|
||||
.setLastName("Carter")
|
||||
.setFirstName("Samanta"),
|
||||
new Person().setId(4L)
|
||||
.setLastName("Daniels")
|
||||
.setFirstName("Joseph"),
|
||||
new Person().setId(5L)
|
||||
.setLastName("English")
|
||||
.setFirstName("Jane"),
|
||||
new Person().setId(6L)
|
||||
.setLastName("Fontana")
|
||||
.setFirstName("Enrique"),
|
||||
// TODO: ADD MORE DATA HERE
|
||||
};
|
||||
|
||||
@Override
|
||||
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
|
||||
Object ret = null;
|
||||
//
|
||||
// Return a random, valid Person object if Person.class is the type of Parameter
|
||||
/// to be resolved. Otherwise return null.
|
||||
if (parameterContext.getParameter()
|
||||
.getType() == Person.class) {
|
||||
ret = VALID_PERSONS[new Random().nextInt(VALID_PERSONS.length)];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
|
||||
boolean ret = false;
|
||||
//
|
||||
// If the Parameter.type == Person.class, then we support it, otherwise, get outta here!
|
||||
if (parameterContext.getParameter()
|
||||
.getType() == Person.class) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.suites;
|
||||
|
||||
import org.junit.platform.runner.JUnitPlatform;
|
||||
import org.junit.platform.suite.api.SelectPackages;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(JUnitPlatform.class)
|
||||
@SelectPackages("com.baeldung")
|
||||
// @SelectClasses({AssertionTest.class, AssumptionTest.class, ExceptionTest.class})
|
||||
public class AllTests {
|
||||
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
com.baeldung.extensions.EmployeeDaoParameterResolver
|
||||
+1
@@ -0,0 +1 @@
|
||||
env=dev
|
||||
@@ -0,0 +1,5 @@
|
||||
#h2 db
|
||||
jdbc.driver=org.h2.Driver
|
||||
jdbc.url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1
|
||||
jdbc.user=sa
|
||||
jdbc.password=
|
||||
@@ -0,0 +1,14 @@
|
||||
*.class
|
||||
|
||||
.settings
|
||||
.project
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
@@ -0,0 +1,7 @@
|
||||
### Relevant articles
|
||||
|
||||
- [Mockito’s Java 8 Features](http://www.baeldung.com/mockito-2-java-8)
|
||||
|
||||
## Mockito 2 and Java 8 Tips
|
||||
|
||||
Examples on how to leverage Java 8 new features with Mockito version 2
|
||||
@@ -0,0 +1,59 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>mockito-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>mockito-2-with-java8</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<!-- testing -->
|
||||
<mockito.version>2.8.9</mockito.version>
|
||||
</properties>
|
||||
</project>
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
public class JobPosition {
|
||||
private String title;
|
||||
|
||||
public JobPosition() {}
|
||||
|
||||
public JobPosition(String title) {
|
||||
super();
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public interface JobService {
|
||||
Optional<JobPosition> findCurrentJobPosition(Person person);
|
||||
|
||||
default boolean assignJobPosition(Person person, JobPosition jobPosition) {
|
||||
if (!findCurrentJobPosition(person).isPresent()) {
|
||||
person.setCurrentJobPosition(jobPosition);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Stream<JobPosition> listJobs(Person person);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
public class Person {
|
||||
private String name;
|
||||
private JobPosition currentJobPosition;
|
||||
|
||||
public Person() {}
|
||||
|
||||
public Person(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public JobPosition getCurrentJobPosition() {
|
||||
return currentJobPosition;
|
||||
}
|
||||
|
||||
public void setCurrentJobPosition(JobPosition currentJobPosition) {
|
||||
this.currentJobPosition = currentJobPosition;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface UnemploymentService {
|
||||
|
||||
boolean personIsEntitledToUnemploymentSupport(Person person);
|
||||
|
||||
Optional<JobPosition> searchJob(Person person, String searchString);
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class UnemploymentServiceImpl implements UnemploymentService {
|
||||
private final JobService jobService;
|
||||
|
||||
public UnemploymentServiceImpl(JobService jobService) {
|
||||
this.jobService = jobService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean personIsEntitledToUnemploymentSupport(Person person) {
|
||||
Optional<JobPosition> optional = jobService.findCurrentJobPosition(person);
|
||||
|
||||
return !optional.isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<JobPosition> searchJob(Person person, String searchString) {
|
||||
Stream<JobPosition> stream = jobService.listJobs(person);
|
||||
|
||||
return stream.filter((j) -> j.getTitle().contains(searchString)).findFirst();
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
|
||||
public class ArgumentMatcherWithLambdaUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private UnemploymentServiceImpl unemploymentService;
|
||||
|
||||
@Mock
|
||||
private JobService jobService;
|
||||
|
||||
@Test
|
||||
public void whenPersonWithJob_thenIsNotEntitled() {
|
||||
Person peter = new Person("Peter");
|
||||
Person linda = new Person("Linda");
|
||||
|
||||
JobPosition teacher = new JobPosition("Teacher");
|
||||
|
||||
when(jobService.findCurrentJobPosition(
|
||||
ArgumentMatchers.argThat((p) -> p.getName().equals("Peter")))
|
||||
).thenReturn(Optional.of(teacher));
|
||||
|
||||
assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(linda));
|
||||
assertFalse(unemploymentService.personIsEntitledToUnemploymentSupport(peter));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.*;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
public class ArgumentMatcherWithoutLambdaUnitTest {
|
||||
|
||||
private class PeterArgumentMatcher implements ArgumentMatcher<Person> {
|
||||
|
||||
@Override
|
||||
public boolean matches(Person p) {
|
||||
return p
|
||||
.getName()
|
||||
.equals("Peter");
|
||||
}
|
||||
}
|
||||
|
||||
@InjectMocks
|
||||
private UnemploymentServiceImpl unemploymentService;
|
||||
|
||||
@Mock
|
||||
private JobService jobService;
|
||||
|
||||
@Test
|
||||
public void whenPersonWithJob_thenIsNotEntitled() {
|
||||
Person peter = new Person("Peter");
|
||||
Person linda = new Person("Linda");
|
||||
|
||||
JobPosition teacher = new JobPosition("Teacher");
|
||||
|
||||
when(jobService.findCurrentJobPosition(
|
||||
ArgumentMatchers.argThat(new PeterArgumentMatcher()))
|
||||
).thenReturn(Optional.of(teacher));
|
||||
|
||||
assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(linda));
|
||||
assertFalse(unemploymentService.personIsEntitledToUnemploymentSupport(peter));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class CustomAnswerWithLambdaUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private UnemploymentServiceImpl unemploymentService;
|
||||
|
||||
@Mock
|
||||
private JobService jobService;
|
||||
|
||||
@Test
|
||||
public void whenPersonWithJobHistory_thenSearchReturnsValue() {
|
||||
Person peter = new Person("Peter");
|
||||
|
||||
assertEquals("Teacher", unemploymentService.searchJob(peter, "").get().getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPersonWithNoJobHistory_thenSearchReturnsEmpty() {
|
||||
Person linda = new Person("Linda");
|
||||
|
||||
assertFalse(unemploymentService.searchJob(linda, "").isPresent());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(jobService.listJobs(any(Person.class))).then((i) ->
|
||||
Stream.of(new JobPosition("Teacher"))
|
||||
.filter(p -> ((Person) i.getArgument(0)).getName().equals("Peter")));
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
public class CustomAnswerWithoutLambdaUnitTest {
|
||||
|
||||
private class PersonAnswer implements Answer<Stream<JobPosition>> {
|
||||
|
||||
@Override
|
||||
public Stream<JobPosition> answer(InvocationOnMock invocation) throws Throwable {
|
||||
Person person = invocation.getArgument(0);
|
||||
|
||||
if(person.getName().equals("Peter")) {
|
||||
return Stream.<JobPosition>builder().add(new JobPosition("Teacher")).build();
|
||||
}
|
||||
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@InjectMocks
|
||||
private UnemploymentServiceImpl unemploymentService;
|
||||
|
||||
@Mock
|
||||
private JobService jobService;
|
||||
|
||||
@Test
|
||||
public void whenPersonWithJobHistory_thenSearchReturnsValue() {
|
||||
Person peter = new Person("Peter");
|
||||
|
||||
assertEquals("Teacher", unemploymentService.searchJob(peter, "").get().getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPersonWithNoJobHistory_thenSearchReturnsEmpty() {
|
||||
Person linda = new Person("Linda");
|
||||
|
||||
assertFalse(unemploymentService.searchJob(linda, "").isPresent());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(jobService.listJobs(any(Person.class))).then(new PersonAnswer());
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
public class JobServiceUnitTest {
|
||||
@Mock
|
||||
private JobService jobService;
|
||||
|
||||
@Test
|
||||
public void givenDefaultMethod_whenCallRealMethod_thenNoExceptionIsRaised() {
|
||||
Person person = new Person();
|
||||
|
||||
when(jobService.findCurrentJobPosition(person)).thenReturn(Optional.of(new JobPosition()));
|
||||
doCallRealMethod().when(jobService).assignJobPosition(Mockito.any(Person.class), Mockito.any(JobPosition.class));
|
||||
|
||||
assertFalse(jobService.assignJobPosition(person, new JobPosition()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenReturnIsOfTypeOptional_whenDefaultValueIsReturned_thenValueIsEmpty() {
|
||||
Person person = new Person();
|
||||
|
||||
when(jobService.findCurrentJobPosition(person)).thenReturn(Optional.empty());
|
||||
doCallRealMethod().when(jobService).assignJobPosition(Mockito.any(Person.class), Mockito.any(JobPosition.class));
|
||||
|
||||
assertTrue(jobService.assignJobPosition(person, new JobPosition()));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package com.baeldung.mockito.java8;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
public class UnemploymentServiceImplUnitTest {
|
||||
@Mock
|
||||
private JobService jobService;
|
||||
|
||||
@InjectMocks
|
||||
private UnemploymentServiceImpl unemploymentService;
|
||||
|
||||
@Test
|
||||
public void givenReturnIsOfTypeOptional_whenMocked_thenValueIsEmpty() {
|
||||
Person person = new Person();
|
||||
|
||||
when(jobService.findCurrentJobPosition(any(Person.class))).thenReturn(Optional.empty());
|
||||
|
||||
assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(person));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenReturnIsOfTypeOptional_whenDefaultValueIsReturned_thenValueIsEmpty() {
|
||||
Person person = new Person();
|
||||
|
||||
// This will fail when Mockito 1 is used
|
||||
assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(person));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenReturnIsOfTypeStream_whenMocked_thenValueIsEmpty() {
|
||||
Person person = new Person();
|
||||
|
||||
when(jobService.listJobs(any(Person.class))).thenReturn(Stream.empty());
|
||||
|
||||
assertFalse(unemploymentService.searchJob(person, "").isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenReturnIsOfTypeStream_whenDefaultValueIsReturned_thenValueIsEmpty() {
|
||||
Person person = new Person();
|
||||
|
||||
// This will fail when Mockito 1 is used
|
||||
assertFalse(unemploymentService.searchJob(person, "").isPresent());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
@@ -0,0 +1,13 @@
|
||||
=========
|
||||
|
||||
## Mockito Cookbooks and Examples
|
||||
|
||||
|
||||
### Relevant Articles:
|
||||
- [Mockito Verify Cookbook](http://www.baeldung.com/mockito-verify)
|
||||
- [Mockito When/Then Cookbook](http://www.baeldung.com/mockito-behavior)
|
||||
- [Mockito – Using Spies](http://www.baeldung.com/mockito-spy)
|
||||
- [Mockito – @Mock, @Spy, @Captor and @InjectMocks](http://www.baeldung.com/mockito-annotations)
|
||||
- [Mockito’s Mock Methods](http://www.baeldung.com/mockito-mock-methods)
|
||||
- [Introduction to PowerMock](http://www.baeldung.com/intro-to-powermock)
|
||||
- [Mocking Exception Throwing using Mockito](http://www.baeldung.com/mockito-exceptions)
|
||||
@@ -0,0 +1,73 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.baeldung</groupId>
|
||||
<artifactId>mockito</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
|
||||
<name>mockito</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- utils -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- web -->
|
||||
|
||||
<!-- test scoped -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4</artifactId>
|
||||
<version>${powermock.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito2</artifactId>
|
||||
<version>${powermock.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>mockito</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<!-- util -->
|
||||
<guava.version>19.0</guava.version>
|
||||
<commons-lang3.version>3.5</commons-lang3.version>
|
||||
|
||||
<!-- testing -->
|
||||
<powermock.version>1.7.0</powermock.version>
|
||||
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN" />
|
||||
<logger name="org.springframework.transaction" level="WARN" />
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.powermockito.introduction;
|
||||
|
||||
class CollaboratorForPartialMocking {
|
||||
|
||||
static String staticMethod() {
|
||||
return "Hello Baeldung!";
|
||||
}
|
||||
|
||||
final String finalMethod() {
|
||||
return "Hello Baeldung!";
|
||||
}
|
||||
|
||||
private String privateMethod() {
|
||||
return "Hello Baeldung!";
|
||||
}
|
||||
|
||||
String privateMethodCaller() {
|
||||
return privateMethod() + " Welcome to the Java world.";
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.powermockito.introduction;
|
||||
|
||||
class CollaboratorWithFinalMethods {
|
||||
|
||||
final String helloMethod() {
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.powermockito.introduction;
|
||||
|
||||
class CollaboratorWithStaticMethods {
|
||||
|
||||
static String firstMethod(String name) {
|
||||
return "Hello " + name + " !";
|
||||
}
|
||||
|
||||
static String secondMethod() {
|
||||
return "Hello no one!";
|
||||
}
|
||||
|
||||
static String thirdMethod() {
|
||||
return "Hello no one again!";
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.powermockito.introduction;
|
||||
|
||||
class LuckyNumberGenerator {
|
||||
|
||||
public int getLuckyNumber(String name) {
|
||||
|
||||
saveIntoDatabase(name);
|
||||
|
||||
if (name == null) {
|
||||
return getDefaultLuckyNumber();
|
||||
}
|
||||
|
||||
return getComputedLuckyNumber(name.length());
|
||||
}
|
||||
|
||||
private void saveIntoDatabase(String name) {
|
||||
// Save the name into the database
|
||||
}
|
||||
|
||||
private int getDefaultLuckyNumber() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
private int getComputedLuckyNumber(int length) {
|
||||
return length < 5 ? 5 : 10000;
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.powermockito.introduction;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.powermock.api.mockito.PowerMockito.doReturn;
|
||||
import static org.powermock.api.mockito.PowerMockito.spy;
|
||||
import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest(fullyQualifiedNames = "com.baeldung.powermockito.introduction.LuckyNumberGenerator")
|
||||
public class LuckyNumberGeneratorTest {
|
||||
|
||||
@Test
|
||||
public final void givenPrivateMethodWithReturn_whenUsingPowerMockito_thenCorrect() throws Exception {
|
||||
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
|
||||
|
||||
when(mock, "getDefaultLuckyNumber").thenReturn(300);
|
||||
|
||||
int result = mock.getLuckyNumber(null);
|
||||
|
||||
assertEquals(300, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenPrivateMethodWithArgumentAndReturn_whenUsingPowerMockito_thenCorrect() throws Exception {
|
||||
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
|
||||
|
||||
doReturn(1).when(mock, "getComputedLuckyNumber", ArgumentMatchers.anyInt());
|
||||
|
||||
int result = mock.getLuckyNumber("Jack");
|
||||
|
||||
assertEquals(1, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenPrivateMethodWithNoArgumentAndReturn_whenUsingPowerMockito_thenCorrect() throws Exception {
|
||||
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
|
||||
|
||||
int result = mock.getLuckyNumber("Tyranosorous");
|
||||
|
||||
verifyPrivate(mock).invoke("saveIntoDatabase", ArgumentMatchers.anyString());
|
||||
assertEquals(10000, result);
|
||||
}
|
||||
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package com.baeldung.powermockito.introduction;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.powermock.api.mockito.PowerMockito.*;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest(fullyQualifiedNames = "com.baeldung.powermockito.introduction.*")
|
||||
public class PowerMockitoIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void givenFinalMethods_whenUsingPowerMockito_thenCorrect() throws Exception {
|
||||
CollaboratorWithFinalMethods mock = mock(CollaboratorWithFinalMethods.class);
|
||||
whenNew(CollaboratorWithFinalMethods.class).withNoArguments().thenReturn(mock);
|
||||
|
||||
CollaboratorWithFinalMethods collaborator = new CollaboratorWithFinalMethods();
|
||||
verifyNew(CollaboratorWithFinalMethods.class).withNoArguments();
|
||||
|
||||
when(collaborator.helloMethod()).thenReturn("Hello Baeldung!");
|
||||
String welcome = collaborator.helloMethod();
|
||||
Mockito.verify(collaborator).helloMethod();
|
||||
assertEquals("Hello Baeldung!", welcome);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void givenStaticMethods_whenUsingPowerMockito_thenCorrect() {
|
||||
mockStatic(CollaboratorWithStaticMethods.class);
|
||||
|
||||
when(CollaboratorWithStaticMethods.firstMethod(Mockito.anyString())).thenReturn("Hello Baeldung!");
|
||||
when(CollaboratorWithStaticMethods.secondMethod()).thenReturn("Nothing special");
|
||||
doThrow(new RuntimeException()).when(CollaboratorWithStaticMethods.class);
|
||||
CollaboratorWithStaticMethods.thirdMethod();
|
||||
|
||||
String firstWelcome = CollaboratorWithStaticMethods.firstMethod("Whoever");
|
||||
String secondWelcome = CollaboratorWithStaticMethods.firstMethod("Whatever");
|
||||
|
||||
assertEquals("Hello Baeldung!", firstWelcome);
|
||||
assertEquals("Hello Baeldung!", secondWelcome);
|
||||
|
||||
verifyStatic(Mockito.times(2));
|
||||
CollaboratorWithStaticMethods.firstMethod(Mockito.anyString());
|
||||
|
||||
verifyStatic(Mockito.never());
|
||||
CollaboratorWithStaticMethods.secondMethod();
|
||||
|
||||
CollaboratorWithStaticMethods.thirdMethod();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPartialMocking_whenUsingPowerMockito_thenCorrect() throws Exception {
|
||||
String returnValue;
|
||||
|
||||
spy(CollaboratorForPartialMocking.class);
|
||||
when(CollaboratorForPartialMocking.staticMethod()).thenReturn("I am a static mock method.");
|
||||
returnValue = CollaboratorForPartialMocking.staticMethod();
|
||||
verifyStatic();
|
||||
CollaboratorForPartialMocking.staticMethod();
|
||||
assertEquals("I am a static mock method.", returnValue);
|
||||
|
||||
CollaboratorForPartialMocking collaborator = new CollaboratorForPartialMocking();
|
||||
CollaboratorForPartialMocking mock = spy(collaborator);
|
||||
|
||||
when(mock.finalMethod()).thenReturn("I am a final mock method.");
|
||||
returnValue = mock.finalMethod();
|
||||
Mockito.verify(mock).finalMethod();
|
||||
assertEquals("I am a final mock method.", returnValue);
|
||||
|
||||
when(mock, "privateMethod").thenReturn("I am a private mock method.");
|
||||
returnValue = mock.privateMethodCaller();
|
||||
verifyPrivate(mock).invoke("privateMethod");
|
||||
assertEquals("I am a private mock method. Welcome to the Java world.", returnValue);
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package org.baeldung.mockito;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
//@RunWith(MockitoJUnitRunner.class)
|
||||
public class MockitoAnnotationIntegrationTest {
|
||||
|
||||
@Mock
|
||||
private List<String> mockedList;
|
||||
|
||||
@Spy
|
||||
private List<String> spiedList = new ArrayList<>();
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
// tests
|
||||
|
||||
@Test
|
||||
public void whenNotUseMockAnnotation_thenCorrect() {
|
||||
final List<String> mockList = Mockito.mock(List.class);
|
||||
mockList.add("one");
|
||||
Mockito.verify(mockList).add("one");
|
||||
assertEquals(0, mockList.size());
|
||||
|
||||
Mockito.when(mockList.size()).thenReturn(100);
|
||||
assertEquals(100, mockList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUseMockAnnotation_thenMockIsInjected() {
|
||||
mockedList.add("one");
|
||||
Mockito.verify(mockedList).add("one");
|
||||
assertEquals(0, mockedList.size());
|
||||
|
||||
Mockito.when(mockedList.size()).thenReturn(100);
|
||||
assertEquals(100, mockedList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNotUseSpyAnnotation_thenCorrect() {
|
||||
final List<String> spyList = Mockito.spy(new ArrayList<String>());
|
||||
spyList.add("one");
|
||||
spyList.add("two");
|
||||
|
||||
Mockito.verify(spyList).add("one");
|
||||
Mockito.verify(spyList).add("two");
|
||||
|
||||
assertEquals(2, spyList.size());
|
||||
|
||||
Mockito.doReturn(100).when(spyList).size();
|
||||
assertEquals(100, spyList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUseSpyAnnotation_thenSpyIsInjectedCorrectly() {
|
||||
spiedList.add("one");
|
||||
spiedList.add("two");
|
||||
|
||||
Mockito.verify(spiedList).add("one");
|
||||
Mockito.verify(spiedList).add("two");
|
||||
|
||||
assertEquals(2, spiedList.size());
|
||||
|
||||
Mockito.doReturn(100).when(spiedList).size();
|
||||
assertEquals(100, spiedList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNotUseCaptorAnnotation_thenCorrect() {
|
||||
final List<String> mockList = Mockito.mock(List.class);
|
||||
final ArgumentCaptor<String> arg = ArgumentCaptor.forClass(String.class);
|
||||
mockList.add("one");
|
||||
Mockito.verify(mockList).add(arg.capture());
|
||||
|
||||
assertEquals("one", arg.getValue());
|
||||
}
|
||||
|
||||
@Captor
|
||||
private
|
||||
ArgumentCaptor<String> argCaptor;
|
||||
|
||||
@Test
|
||||
public void whenUseCaptorAnnotation_thenTheSam() {
|
||||
mockedList.add("one");
|
||||
Mockito.verify(mockedList).add(argCaptor.capture());
|
||||
|
||||
assertEquals("one", argCaptor.getValue());
|
||||
}
|
||||
|
||||
@Mock
|
||||
private Map<String, String> wordMap;
|
||||
|
||||
@InjectMocks
|
||||
private MyDictionary dic = new MyDictionary();
|
||||
|
||||
@Test
|
||||
public void whenUseInjectMocksAnnotation_thenCorrect() {
|
||||
Mockito.when(wordMap.get("aWord")).thenReturn("aMeaning");
|
||||
|
||||
assertEquals("aMeaning", dic.getMeaning("aWord"));
|
||||
}
|
||||
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package org.baeldung.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class MockitoConfigExamplesIntegrationTest {
|
||||
|
||||
// tests
|
||||
|
||||
@Test
|
||||
public final void whenMockReturnBehaviorIsConfigured_thenBehaviorIsVerified() {
|
||||
final MyList listMock = Mockito.mock(MyList.class);
|
||||
when(listMock.add(anyString())).thenReturn(false);
|
||||
|
||||
final boolean added = listMock.add(randomAlphabetic(6));
|
||||
assertThat(added, is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenMockReturnBehaviorIsConfigured2_thenBehaviorIsVerified() {
|
||||
final MyList listMock = Mockito.mock(MyList.class);
|
||||
doReturn(false).when(listMock).add(anyString());
|
||||
|
||||
final boolean added = listMock.add(randomAlphabetic(6));
|
||||
assertThat(added, is(false));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public final void givenMethodIsConfiguredToThrowException_whenCallingMethod_thenExceptionIsThrown() {
|
||||
final MyList listMock = Mockito.mock(MyList.class);
|
||||
when(listMock.add(anyString())).thenThrow(IllegalStateException.class);
|
||||
|
||||
listMock.add(randomAlphabetic(6));
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public final void whenMethodHasNoReturnType_whenConfiguringBehaviorOfMethod_thenPossible() {
|
||||
final MyList listMock = Mockito.mock(MyList.class);
|
||||
doThrow(NullPointerException.class).when(listMock).clear();
|
||||
|
||||
listMock.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenBehaviorIsConfiguredToThrowExceptionOnSecondCall_whenCallingOnlyOnce_thenNoExceptionIsThrown() {
|
||||
final MyList listMock = Mockito.mock(MyList.class);
|
||||
when(listMock.add(anyString())).thenReturn(false).thenThrow(IllegalStateException.class);
|
||||
|
||||
listMock.add(randomAlphabetic(6));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public final void givenBehaviorIsConfiguredToThrowExceptionOnSecondCall_whenCallingTwice_thenExceptionIsThrown() {
|
||||
final MyList listMock = Mockito.mock(MyList.class);
|
||||
when(listMock.add(anyString())).thenReturn(false).thenThrow(IllegalStateException.class);
|
||||
|
||||
listMock.add(randomAlphabetic(6));
|
||||
listMock.add(randomAlphabetic(6));
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenMockMethodCallIsConfiguredToCallTheRealMethod_thenRealMethodIsCalled() {
|
||||
final MyList listMock = Mockito.mock(MyList.class);
|
||||
when(listMock.size()).thenCallRealMethod();
|
||||
|
||||
assertThat(listMock.size(), equalTo(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenMockMethodCallIsConfiguredWithCustomAnswer_thenRealMethodIsCalled() {
|
||||
final MyList listMock = Mockito.mock(MyList.class);
|
||||
doAnswer(invocation -> "Always the same").when(listMock).get(anyInt());
|
||||
|
||||
final String element = listMock.get(1);
|
||||
assertThat(element, is(equalTo("Always the same")));
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public final void givenSpy_whenConfiguringBehaviorOfSpy_thenCorrectlyConfigured() {
|
||||
final MyList instance = new MyList();
|
||||
final MyList spy = Mockito.spy(instance);
|
||||
|
||||
doThrow(NullPointerException.class).when(spy).size();
|
||||
spy.size();
|
||||
}
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package org.baeldung.mockito;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class MockitoExceptionIntegrationTest {
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void whenConfigNonVoidRetunMethodToThrowEx_thenExIsThrown() {
|
||||
MyDictionary dictMock = mock(MyDictionary.class);
|
||||
when(dictMock.getMeaning(anyString())).thenThrow(NullPointerException.class);
|
||||
|
||||
dictMock.getMeaning("word");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void whenConfigVoidRetunMethodToThrowEx_thenExIsThrown() {
|
||||
MyDictionary dictMock = mock(MyDictionary.class);
|
||||
doThrow(IllegalStateException.class).when(dictMock)
|
||||
.add(anyString(), anyString());
|
||||
|
||||
dictMock.add("word", "meaning");
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void whenConfigNonVoidRetunMethodToThrowExWithNewExObj_thenExIsThrown() {
|
||||
MyDictionary dictMock = mock(MyDictionary.class);
|
||||
when(dictMock.getMeaning(anyString())).thenThrow(new NullPointerException("Error occurred"));
|
||||
|
||||
dictMock.getMeaning("word");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void whenConfigVoidRetunMethodToThrowExWithNewExObj_thenExIsThrown() {
|
||||
MyDictionary dictMock = mock(MyDictionary.class);
|
||||
doThrow(new IllegalStateException("Error occurred")).when(dictMock)
|
||||
.add(anyString(), anyString());
|
||||
|
||||
dictMock.add("word", "meaning");
|
||||
}
|
||||
|
||||
// =====
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void givenSpy_whenConfigNonVoidRetunMethodToThrowEx_thenExIsThrown() {
|
||||
MyDictionary dict = new MyDictionary();
|
||||
MyDictionary spy = Mockito.spy(dict);
|
||||
|
||||
when(spy.getMeaning(anyString())).thenThrow(NullPointerException.class);
|
||||
spy.getMeaning("word");
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package org.baeldung.mockito;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.MockSettings;
|
||||
import org.mockito.exceptions.verification.TooLittleActualInvocations;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
public class MockitoMockIntegrationTest {
|
||||
|
||||
private static class CustomAnswer implements Answer<Boolean> {
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocation) throws Throwable {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Rule
|
||||
private ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void whenUsingSimpleMock_thenCorrect() {
|
||||
MyList listMock = mock(MyList.class);
|
||||
when(listMock.add(anyString())).thenReturn(false);
|
||||
boolean added = listMock.add(randomAlphabetic(6));
|
||||
|
||||
verify(listMock).add(anyString());
|
||||
assertThat(added, is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingMockWithName_thenCorrect() {
|
||||
MyList listMock = mock(MyList.class, "myMock");
|
||||
when(listMock.add(anyString())).thenReturn(false);
|
||||
listMock.add(randomAlphabetic(6));
|
||||
|
||||
thrown.expect(TooLittleActualInvocations.class);
|
||||
thrown.expectMessage(containsString("myMock.add"));
|
||||
|
||||
verify(listMock, times(2)).add(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingMockWithAnswer_thenCorrect() {
|
||||
MyList listMock = mock(MyList.class, new CustomAnswer());
|
||||
boolean added = listMock.add(randomAlphabetic(6));
|
||||
|
||||
verify(listMock).add(anyString());
|
||||
assertThat(added, is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingMockWithSettings_thenCorrect() {
|
||||
MockSettings customSettings = withSettings().defaultAnswer(new CustomAnswer());
|
||||
MyList listMock = mock(MyList.class, customSettings);
|
||||
boolean added = listMock.add(randomAlphabetic(6));
|
||||
|
||||
verify(listMock).add(anyString());
|
||||
assertThat(added, is(false));
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package org.baeldung.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MockitoSpyIntegrationTest {
|
||||
|
||||
@Spy
|
||||
private List<String> aSpyList = new ArrayList<String>();
|
||||
|
||||
@Test
|
||||
public void whenSpyingOnList_thenCorrect() {
|
||||
final List<String> list = new ArrayList<String>();
|
||||
final List<String> spyList = Mockito.spy(list);
|
||||
|
||||
spyList.add("one");
|
||||
spyList.add("two");
|
||||
|
||||
Mockito.verify(spyList).add("one");
|
||||
Mockito.verify(spyList).add("two");
|
||||
|
||||
assertEquals(2, spyList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingTheSpyAnnotation_thenObjectIsSpied() {
|
||||
aSpyList.add("one");
|
||||
aSpyList.add("two");
|
||||
|
||||
Mockito.verify(aSpyList).add("one");
|
||||
Mockito.verify(aSpyList).add("two");
|
||||
|
||||
assertEquals(2, aSpyList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenStubASpy_thenStubbed() {
|
||||
final List<String> list = new ArrayList<String>();
|
||||
final List<String> spyList = Mockito.spy(list);
|
||||
|
||||
assertEquals(0, spyList.size());
|
||||
|
||||
Mockito.doReturn(100).when(spyList).size();
|
||||
assertEquals(100, spyList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCreateMock_thenCreated() {
|
||||
final List<String> mockedList = Mockito.mock(ArrayList.class);
|
||||
|
||||
mockedList.add("one");
|
||||
Mockito.verify(mockedList).add("one");
|
||||
|
||||
assertEquals(0, mockedList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCreateSpy_thenCreate() {
|
||||
final List<String> spyList = Mockito.spy(new ArrayList<String>());
|
||||
|
||||
spyList.add("one");
|
||||
Mockito.verify(spyList).add("one");
|
||||
|
||||
assertEquals(1, spyList.size());
|
||||
}
|
||||
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package org.baeldung.mockito;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.exceptions.verification.NoInteractionsWanted;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class MockitoVerifyExamplesIntegrationTest {
|
||||
|
||||
// tests
|
||||
|
||||
@Test
|
||||
public final void givenInteractionWithMockOccurred_whenVerifyingInteraction_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
mockedList.size();
|
||||
verify(mockedList).size();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenOneInteractionWithMockOccurred_whenVerifyingNumberOfInteractions_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
mockedList.size();
|
||||
verify(mockedList, times(1)).size();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenNoInteractionWithMockOccurred_whenVerifyingInteractions_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
verifyZeroInteractions(mockedList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenNoInteractionWithMethodOfMockOccurred_whenVerifyingInteractions_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
verify(mockedList, times(0)).size();
|
||||
}
|
||||
|
||||
@Test(expected = NoInteractionsWanted.class)
|
||||
public final void givenUnverifiedInteraction_whenVerifyingNoUnexpectedInteractions_thenFail() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
mockedList.size();
|
||||
mockedList.clear();
|
||||
|
||||
verify(mockedList).size();
|
||||
verifyNoMoreInteractions(mockedList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenVerifyingOrderOfInteractions_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
mockedList.size();
|
||||
mockedList.add("a parameter");
|
||||
mockedList.clear();
|
||||
|
||||
final InOrder inOrder = Mockito.inOrder(mockedList);
|
||||
inOrder.verify(mockedList).size();
|
||||
inOrder.verify(mockedList).add("a parameter");
|
||||
inOrder.verify(mockedList).clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenVerifyingAnInteractionHasNotOccurred_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
mockedList.size();
|
||||
|
||||
verify(mockedList, never()).clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenVerifyingAnInteractionHasOccurredAtLeastOnce_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
mockedList.clear();
|
||||
mockedList.clear();
|
||||
mockedList.clear();
|
||||
|
||||
verify(mockedList, atLeast(1)).clear();
|
||||
verify(mockedList, atMost(10)).clear();
|
||||
}
|
||||
|
||||
// with arguments
|
||||
|
||||
@Test
|
||||
public final void whenVerifyingAnInteractionWithExactArgument_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
mockedList.add("test");
|
||||
|
||||
verify(mockedList).add("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenVerifyingAnInteractionWithAnyArgument_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
mockedList.add("test");
|
||||
|
||||
verify(mockedList).add(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenVerifyingAnInteractionWithArgumentCapture_thenCorrect() {
|
||||
final List<String> mockedList = mock(MyList.class);
|
||||
mockedList.addAll(Lists.<String>newArrayList("someElement"));
|
||||
final ArgumentCaptor<List> argumentCaptor = ArgumentCaptor.forClass(List.class);
|
||||
verify(mockedList).addAll(argumentCaptor.capture());
|
||||
final List<String> capturedArgument = argumentCaptor.<List<String>>getValue();
|
||||
assertThat(capturedArgument, hasItem("someElement"));
|
||||
}
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package org.baeldung.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import static org.mockito.Matchers.any;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MockitoVoidMethodsTest {
|
||||
|
||||
@Test
|
||||
public void whenAddCalledVerified() {
|
||||
MyList mockVoid = mock(MyList.class);
|
||||
mockVoid.add(0, "");
|
||||
verify(mockVoid, times(1)).add(0, "");
|
||||
}
|
||||
|
||||
@Test(expected = Exception.class)
|
||||
public void givenNull_addThrows() {
|
||||
MyList mockVoid = mock(MyList.class);
|
||||
doThrow().when(mockVoid).add(isA(Integer.class), isNull());
|
||||
mockVoid.add(0, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddCalledValueCaptured() {
|
||||
MyList mockVoid = mock(MyList.class);
|
||||
ArgumentCaptor<String> valueCapture = ArgumentCaptor.forClass(String.class);
|
||||
doNothing().when(mockVoid).add(any(Integer.class), valueCapture.capture());
|
||||
mockVoid.add(0, "captured");
|
||||
assertEquals("captured", valueCapture.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddCalledAnswered() {
|
||||
MyList mockVoid = mock(MyList.class);
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
Object arg0 = invocation.getArgument(0);
|
||||
Object arg1 = invocation.getArgument(1);
|
||||
|
||||
//do something with the arguments here
|
||||
assertEquals(3, arg0);
|
||||
assertEquals("answer me", arg1);
|
||||
|
||||
return null;
|
||||
}).when(mockVoid).add(any(Integer.class), any(String.class));
|
||||
mockVoid.add(3, "answer me");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddCalledRealMethodCalled() {
|
||||
MyList mockVoid = mock(MyList.class);
|
||||
doCallRealMethod().when(mockVoid).add(any(Integer.class), any(String.class));
|
||||
mockVoid.add(1, "real");
|
||||
verify(mockVoid, times(1)).add(1, "real");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.baeldung.mockito;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class MyDictionary {
|
||||
|
||||
private Map<String, String> wordMap;
|
||||
|
||||
MyDictionary() {
|
||||
wordMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public void add(final String word, final String meaning) {
|
||||
wordMap.put(word, meaning);
|
||||
}
|
||||
|
||||
String getMeaning(final String word) {
|
||||
return wordMap.get(word);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.baeldung.mockito;
|
||||
|
||||
import java.util.AbstractList;
|
||||
|
||||
class MyList extends AbstractList<String> {
|
||||
|
||||
@Override
|
||||
public String get(final int index) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, String element) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
## Relevant articles:
|
||||
|
||||
- [Introduction to MockServer](http://www.baeldung.com/mockserver)
|
||||
- [JMockit Advanced Usage](http://www.baeldung.com/jmockit-advanced-usage)
|
||||
- [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations)
|
||||
- [JMockit 101](http://www.baeldung.com/jmockit-101)
|
||||
- [Mockito vs EasyMock vs JMockit](http://www.baeldung.com/mockito-vs-easymock-vs-jmockit)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user