renamed back to testing-modules, pulled together testing-modules-2 modules into single module
This commit is contained in:
5
testing-modules/README.md
Normal file
5
testing-modules/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
## Testing Modules
|
||||
|
||||
This is a aggregator module containing several modules focused on testing libraries.
|
||||
|
||||
3
testing-modules/easy-random/README.md
Normal file
3
testing-modules/easy-random/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## Relevant Articles:
|
||||
|
||||
- [Quick Guide to EasyRandom in Java](https://www.baeldung.com/java-easy-random)
|
||||
24
testing-modules/easy-random/pom.xml
Normal file
24
testing-modules/easy-random/pom.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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>
|
||||
<artifactId>easy-random</artifactId>
|
||||
<name>easy-random</name>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jeasy</groupId>
|
||||
<artifactId>easy-random-core</artifactId>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.baeldung.easy.random.model;
|
||||
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class Department {
|
||||
private String depName;
|
||||
|
||||
public Department(String depName) {
|
||||
this.depName = depName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", Department.class.getSimpleName() + "[", "]").add("depName='" + depName + "'")
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.baeldung.easy.random.model;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Employee {
|
||||
|
||||
private long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private Department department;
|
||||
private Collection<Employee> coworkers;
|
||||
private Map<YearQuarter, Grade> quarterGrades;
|
||||
|
||||
public Employee(long id, String firstName, String lastName, Department department) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
Employee employee = (Employee) o;
|
||||
return id == employee.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Department getDepartment() {
|
||||
return department;
|
||||
}
|
||||
|
||||
public Collection<Employee> getCoworkers() {
|
||||
return Collections.unmodifiableCollection(coworkers);
|
||||
}
|
||||
|
||||
public Map<YearQuarter, Grade> getQuarterGrades() {
|
||||
return Collections.unmodifiableMap(quarterGrades);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", Employee.class.getSimpleName() + "[", "]").add("id=" + id)
|
||||
.add("firstName='" + firstName + "'")
|
||||
.add("lastName='" + lastName + "'")
|
||||
.add("department=" + department)
|
||||
.add("coworkers size=" + ((coworkers == null) ? 0 : coworkers.size()))
|
||||
.add("quarterGrades=" + quarterGrades)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.baeldung.easy.random.model;
|
||||
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class Grade {
|
||||
|
||||
private int grade;
|
||||
|
||||
public Grade(int grade) {
|
||||
this.grade = grade;
|
||||
}
|
||||
|
||||
public int getGrade() {
|
||||
return grade;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", Grade.class.getSimpleName() + "[", "]").add("grade=" + grade)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.baeldung.easy.random.model;
|
||||
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class Person {
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private Integer age;
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public Integer getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", Person.class.getSimpleName() + "[", "]").add("firstName='" + firstName + "'")
|
||||
.add("lastName='" + lastName + "'")
|
||||
.add("age=" + age)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.baeldung.easy.random.model;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class YearQuarter {
|
||||
|
||||
private LocalDate startDate;
|
||||
private LocalDate endDate;
|
||||
|
||||
public YearQuarter(LocalDate startDate) {
|
||||
this.startDate = startDate;
|
||||
autoAdjustEndDate();
|
||||
}
|
||||
|
||||
private void autoAdjustEndDate() {
|
||||
endDate = startDate.plusMonths(3L);
|
||||
}
|
||||
|
||||
public LocalDate getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public LocalDate getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
YearQuarter quarter = (YearQuarter) o;
|
||||
return Objects.equals(startDate, quarter.startDate) && Objects.equals(endDate, quarter.endDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(startDate, endDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", YearQuarter.class.getSimpleName() + "[", "]").add("startDate=" + startDate)
|
||||
.add("endDate=" + endDate)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.baeldung.easy.random.randomizer;
|
||||
|
||||
import org.baeldung.easy.random.model.YearQuarter;
|
||||
import org.jeasy.random.api.Randomizer;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
|
||||
public class YearQuarterRandomizer implements Randomizer<YearQuarter> {
|
||||
|
||||
private LocalDate date = LocalDate.of(1990, Month.SEPTEMBER, 25);
|
||||
|
||||
@Override
|
||||
public YearQuarter getRandomValue() {
|
||||
date = date.plusMonths(3);
|
||||
return new YearQuarter(date);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.baeldung.easy.random;
|
||||
|
||||
import org.baeldung.easy.random.model.Employee;
|
||||
import org.baeldung.easy.random.model.Person;
|
||||
import org.baeldung.easy.random.model.YearQuarter;
|
||||
import org.baeldung.easy.random.randomizer.YearQuarterRandomizer;
|
||||
import org.jeasy.random.EasyRandom;
|
||||
import org.jeasy.random.EasyRandomParameters;
|
||||
import org.jeasy.random.FieldPredicates;
|
||||
import org.jeasy.random.TypePredicates;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class EasyRandomUnitTest {
|
||||
|
||||
@Test
|
||||
void givenDefaultConfiguration_thenGenerateSingleObject() {
|
||||
EasyRandom generator = new EasyRandom();
|
||||
Person person = generator.nextObject(Person.class);
|
||||
|
||||
assertNotNull(person.getAge());
|
||||
assertNotNull(person.getFirstName());
|
||||
assertNotNull(person.getLastName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenDefaultConfiguration_thenGenerateObjectsList() {
|
||||
EasyRandom generator = new EasyRandom();
|
||||
List<Person> persons = generator.objects(Person.class, 5)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(5, persons.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenCustomConfiguration_thenGenerateSingleEmployee() {
|
||||
EasyRandomParameters parameters = new EasyRandomParameters();
|
||||
parameters.stringLengthRange(3, 3);
|
||||
parameters.collectionSizeRange(5, 5);
|
||||
parameters.excludeField(FieldPredicates.named("lastName").and(FieldPredicates.inClass(Employee.class)));
|
||||
parameters.excludeType(TypePredicates.inPackage("not.existing.pkg"));
|
||||
parameters.randomize(YearQuarter.class, new YearQuarterRandomizer());
|
||||
|
||||
EasyRandom generator = new EasyRandom(parameters);
|
||||
Employee employee = generator.nextObject(Employee.class);
|
||||
|
||||
assertEquals(3, employee.getFirstName().length());
|
||||
assertEquals(5, employee.getCoworkers().size());
|
||||
assertEquals(5, employee.getQuarterGrades().size());
|
||||
assertNotNull(employee.getDepartment());
|
||||
|
||||
assertNull(employee.getLastName());
|
||||
|
||||
for (YearQuarter key : employee.getQuarterGrades().keySet()) {
|
||||
assertEquals(key.getStartDate(), key.getEndDate().minusMonths(3L));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
30
testing-modules/easymock/pom.xml
Normal file
30
testing-modules/easymock/pom.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0"?>
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>easymock</artifactId>
|
||||
<name>easymock</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>testing-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<version>${easymock.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<easymock.version>4.0.2</easymock.version>
|
||||
</properties>
|
||||
</project>
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.testing.easymock;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class ForecastProcessor {
|
||||
private WeatherService weatherService;
|
||||
|
||||
public BigDecimal getMaximumTemperature(String locationName) {
|
||||
|
||||
Location location = new Location(locationName);
|
||||
|
||||
try {
|
||||
weatherService.populateTemperature(location);
|
||||
} catch (ServiceUnavailableException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return location.getMaximumTemparature();
|
||||
}
|
||||
|
||||
public WeatherService getWeatherService() {
|
||||
return weatherService;
|
||||
}
|
||||
|
||||
public void setWeatherService(WeatherService weatherService) {
|
||||
this.weatherService = weatherService;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.testing.easymock;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class Location {
|
||||
private String name;
|
||||
private BigDecimal minimumTemperature;
|
||||
private BigDecimal maximumTemparature;
|
||||
|
||||
public Location(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public BigDecimal getMinimumTemperature() {
|
||||
return minimumTemperature;
|
||||
}
|
||||
|
||||
public void setMinimumTemperature(BigDecimal minimumTemperature) {
|
||||
this.minimumTemperature = minimumTemperature;
|
||||
}
|
||||
|
||||
public BigDecimal getMaximumTemparature() {
|
||||
return maximumTemparature;
|
||||
}
|
||||
|
||||
public void setMaximumTemparature(BigDecimal maximumTemparature) {
|
||||
this.maximumTemparature = maximumTemparature;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.baeldung.testing.easymock;
|
||||
|
||||
public class ServiceUnavailableException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 6961151537340723535L;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.baeldung.testing.easymock;
|
||||
|
||||
public interface WeatherService {
|
||||
void populateTemperature(Location location) throws ServiceUnavailableException;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.baeldung.testing.easymock;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.easymock.EasyMockRule;
|
||||
import org.easymock.Mock;
|
||||
import org.easymock.TestSubject;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ForecastProcessorUnitTest {
|
||||
private static int MAX_TEMP = 90;
|
||||
|
||||
@Rule
|
||||
public EasyMockRule rule = new EasyMockRule(this);
|
||||
|
||||
@TestSubject
|
||||
private ForecastProcessor forecastProcessor = new ForecastProcessor();
|
||||
|
||||
@Mock
|
||||
private WeatherService mockWeatherService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
forecastProcessor.setWeatherService(mockWeatherService);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void givenLocationName_whenWeatherServicePopulatesTemperatures_thenMaxTempReturned() throws ServiceUnavailableException {
|
||||
mockWeatherService.populateTemperature(EasyMock.anyObject(Location.class));
|
||||
EasyMock.expectLastCall()
|
||||
.andAnswer(() -> {
|
||||
Location passedLocation = (Location) EasyMock.getCurrentArguments()[0];
|
||||
passedLocation.setMaximumTemparature(new BigDecimal(MAX_TEMP));
|
||||
passedLocation.setMinimumTemperature(new BigDecimal(MAX_TEMP - 10));
|
||||
return null;
|
||||
});
|
||||
EasyMock.replay(mockWeatherService);
|
||||
BigDecimal maxTemperature = forecastProcessor.getMaximumTemperature("New York");
|
||||
EasyMock.verify(mockWeatherService);
|
||||
assertThat(maxTemperature, equalTo(new BigDecimal(MAX_TEMP)));
|
||||
}
|
||||
}
|
||||
5
testing-modules/gatling/README.md
Normal file
5
testing-modules/gatling/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
### Relevant Articles:
|
||||
- [Intro to Gatling](http://www.baeldung.com/introduction-to-gatling)
|
||||
|
||||
### Running a simualtion
|
||||
- To run a simulation use "simulation" profile, command - `mvn install -Psimulation -Dgib.enabled=false`
|
||||
136
testing-modules/gatling/pom.xml
Normal file
136
testing-modules/gatling/pom.xml
Normal file
@@ -0,0 +1,136 @@
|
||||
<?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>
|
||||
<name>gatling</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<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>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>simulation</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.gatling</groupId>
|
||||
<artifactId>gatling-maven-plugin</artifactId>
|
||||
<version>${gatling-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>execute</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<disableCompiler>true</disableCompiler>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<encoding>UTF-8</encoding>
|
||||
<scala.version>2.12.6</scala.version> <!--2.11.12 --> <!--2.12.6 -->
|
||||
<gatling.version>2.3.1</gatling.version> <!--2.2.5 --> <!--2.3.1 -->
|
||||
<scala-maven-plugin.version>3.2.2</scala-maven-plugin.version> <!--3.2.2 --> <!--3.3.2 -->
|
||||
<gatling-maven-plugin.version>2.2.4</gatling-maven-plugin.version> <!--2.2.1 --> <!--2.2.4 -->
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
127
testing-modules/gatling/src/test/resources/gatling.conf
Normal file
127
testing-modules/gatling/src/test/resources/gatling.conf
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
22
testing-modules/gatling/src/test/resources/logback.xml
Normal file
22
testing-modules/gatling/src/test/resources/logback.xml
Normal file
@@ -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>
|
||||
53
testing-modules/gatling/src/test/resources/recorder.conf
Normal file
53
testing-modules/gatling/src/test/resources/recorder.conf
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
13
testing-modules/gatling/src/test/scala/Engine.scala
Normal file
13
testing-modules/gatling/src/test/scala/Engine.scala
Normal file
@@ -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)
|
||||
}
|
||||
22
testing-modules/gatling/src/test/scala/IDEPathHelper.scala
Normal file
22
testing-modules/gatling/src/test/scala/IDEPathHelper.scala
Normal file
@@ -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"
|
||||
}
|
||||
12
testing-modules/gatling/src/test/scala/Recorder.scala
Normal file
12
testing-modules/gatling/src/test/scala/Recorder.scala
Normal file
@@ -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,45 @@
|
||||
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)
|
||||
}
|
||||
1
testing-modules/groovy-spock/.gitignore
vendored
Normal file
1
testing-modules/groovy-spock/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/report-*.json
|
||||
5
testing-modules/groovy-spock/README.md
Normal file
5
testing-modules/groovy-spock/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
### Relevant articles
|
||||
|
||||
- [Introduction to Testing with Spock and Groovy](http://www.baeldung.com/groovy-spock)
|
||||
- [Difference Between Stub, Mock, and Spy in the Spock Framework](https://www.baeldung.com/spock-stub-mock-spy)
|
||||
- [Guide to Spock Extensions](https://www.baeldung.com/spock-extensions)
|
||||
56
testing-modules/groovy-spock/pom.xml
Normal file
56
testing-modules/groovy-spock/pom.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?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>
|
||||
<name>groovy-spock</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spockframework</groupId>
|
||||
<artifactId>spock-core</artifactId>
|
||||
<version>${spock-core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>${groovy-all.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmavenplus</groupId>
|
||||
<artifactId>gmavenplus-plugin</artifactId>
|
||||
<version>${gmavenplus-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<spock-core.version>1.3-groovy-2.4</spock-core.version>
|
||||
<groovy-all.version>2.4.7</groovy-all.version>
|
||||
<gmavenplus-plugin.version>1.5</gmavenplus-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,7 @@
|
||||
package mocks;
|
||||
|
||||
public interface EventPublisher {
|
||||
|
||||
void publish(String addedOfferId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package mocks;
|
||||
|
||||
public class ExternalItemProviderException extends RuntimeException {
|
||||
|
||||
}
|
||||
36
testing-modules/groovy-spock/src/main/java/mocks/Item.java
Normal file
36
testing-modules/groovy-spock/src/main/java/mocks/Item.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package mocks;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Item {
|
||||
private final String id;
|
||||
private final String name;
|
||||
|
||||
public Item(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Item item = (Item) o;
|
||||
return Objects.equals(id, item.id) &&
|
||||
Objects.equals(name, item.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package mocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ItemProvider {
|
||||
|
||||
List<Item> getItems(List<String> itemIds);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package mocks;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ItemService {
|
||||
private final ItemProvider itemProvider;
|
||||
private final EventPublisher eventPublisher;
|
||||
|
||||
|
||||
public ItemService(ItemProvider itemProvider, EventPublisher eventPublisher) {
|
||||
this.itemProvider = itemProvider;
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
List<Item> getAllItemsSortedByName(List<String> itemIds) {
|
||||
List<Item> items;
|
||||
try{
|
||||
items = itemProvider.getItems(itemIds);
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ExternalItemProviderException();
|
||||
}
|
||||
return items.stream()
|
||||
.sorted(Comparator.comparing(Item::getName))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
void saveItems(List<String> itemIds) {
|
||||
List<String> notEmptyOfferIds = itemIds.stream()
|
||||
.filter(itemId -> !itemId.isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
// save in database
|
||||
notEmptyOfferIds.forEach(eventPublisher::publish);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package mocks;
|
||||
|
||||
public class LoggingEventPublisher implements EventPublisher {
|
||||
|
||||
@Override
|
||||
public void publish(String addedOfferId) {
|
||||
System.out.println("I've published: " + addedOfferId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,20 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.Narrative
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Title
|
||||
|
||||
|
||||
@Title("""This title is easy to read for humans""")
|
||||
class CustomTitleTest extends Specification {
|
||||
|
||||
}
|
||||
|
||||
@Narrative("""
|
||||
as a user
|
||||
i want to save favourite items
|
||||
and then get the list of them
|
||||
""")
|
||||
class NarrativeDescriptionTest extends Specification {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Specification
|
||||
|
||||
|
||||
class IgnoreIfTest extends Specification {
|
||||
|
||||
@IgnoreIf({System.getProperty("os.name").contains("windows")})
|
||||
def "I won't run on windows"() {
|
||||
expect:
|
||||
true
|
||||
}
|
||||
|
||||
@IgnoreIf({ os.isWindows() })
|
||||
def "I'm using Spock helper classes to run only on windows"() {
|
||||
expect:
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.IgnoreRest
|
||||
import spock.lang.Specification
|
||||
|
||||
|
||||
class IgnoreRestTest extends Specification {
|
||||
|
||||
def "I won't run"() { }
|
||||
|
||||
@IgnoreRest
|
||||
def 'I will run'() { }
|
||||
|
||||
def "I won't run too"() { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.Ignore
|
||||
import spock.lang.Specification
|
||||
|
||||
@Ignore
|
||||
class IgnoreTest extends Specification {
|
||||
|
||||
@Ignore
|
||||
def "I won't be executed"() {
|
||||
expect:
|
||||
true
|
||||
}
|
||||
|
||||
def 'Example test'() {
|
||||
expect:
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.Issue
|
||||
import spock.lang.Specification
|
||||
|
||||
|
||||
class IssueTest extends Specification {
|
||||
|
||||
|
||||
@Issue("http://jira.org/issues/LO-531")
|
||||
def 'single issue'() {
|
||||
}
|
||||
|
||||
@Issue(["http://jira.org/issues/LO-531", "http://jira.org/issues/LO-123"])
|
||||
def 'multiple issues'() {
|
||||
}
|
||||
|
||||
@Issue("LO-1000")
|
||||
def "I'm using Spock configuration file"() {
|
||||
expect:
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.PendingFeature
|
||||
|
||||
class PendingFeatureTest {
|
||||
|
||||
@PendingFeature
|
||||
def 'test for not implemented yet feature'() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.Requires
|
||||
import spock.lang.Specification
|
||||
|
||||
|
||||
class RequiresTest extends Specification {
|
||||
|
||||
@Requires({ System.getProperty("os.name").contains("windows") })
|
||||
def "I will run only on Windows"() {
|
||||
expect:
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.Specification
|
||||
import spock.util.environment.RestoreSystemProperties
|
||||
|
||||
|
||||
class RestoreSystemPropertiesTest extends Specification {
|
||||
|
||||
@RestoreSystemProperties
|
||||
def 'all environment variables will be saved before execution and restored after tests'() {
|
||||
given:
|
||||
System.setProperty('os.name', 'Mac OS')
|
||||
|
||||
expect:
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.Retry
|
||||
import spock.lang.Specification
|
||||
|
||||
@Retry
|
||||
class RetryTest extends Specification {
|
||||
|
||||
@Retry
|
||||
def 'I will retry three times'() { }
|
||||
|
||||
@Retry(exceptions = [RuntimeException])
|
||||
def 'I will retry only on RuntimeException'() { }
|
||||
|
||||
@Retry(condition = { failure.message.contains('error') })
|
||||
def 'I will retry with a specific message'() { }
|
||||
|
||||
@Retry(delay = 1000)
|
||||
def 'I will retry after 1000 millis'() { }
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.See
|
||||
import spock.lang.Specification
|
||||
|
||||
|
||||
class SeeTest extends Specification {
|
||||
|
||||
|
||||
@See("https://example.org")
|
||||
def 'Look at the reference'() {
|
||||
|
||||
}
|
||||
|
||||
@See(["https://example.org/first", "https://example.org/first"])
|
||||
def 'Look at the references'() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package extensions
|
||||
|
||||
import org.junit.Ignore
|
||||
import spock.lang.Specification
|
||||
|
||||
|
||||
class StackTraceTest extends Specification {
|
||||
|
||||
def 'stkacktrace'() {
|
||||
// expect:
|
||||
// throw new RuntimeException("blabla")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Stepwise
|
||||
|
||||
|
||||
@Stepwise
|
||||
class StepwiseTest extends Specification {
|
||||
|
||||
def 'I will run as first'() { }
|
||||
|
||||
def 'I will run as second'() { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package extensions
|
||||
|
||||
import mocks.ItemService
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Subject
|
||||
|
||||
|
||||
class SubjectTest extends Specification {
|
||||
|
||||
@Subject
|
||||
ItemService itemService // initialization here...
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package extensions
|
||||
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Timeout
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@Timeout(5)
|
||||
class TimeoutTest extends Specification {
|
||||
|
||||
@Timeout(1)
|
||||
def 'I have one second to finish'() {
|
||||
|
||||
}
|
||||
|
||||
def 'I will have 5 seconds timeout'() {}
|
||||
|
||||
@Timeout(value = 200, unit = TimeUnit.SECONDS)
|
||||
def 'I will fail after 200 millis'() {
|
||||
expect:
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package mocks
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
class ItemServiceUnitTest extends Specification {
|
||||
|
||||
ItemProvider itemProvider
|
||||
ItemService itemService
|
||||
EventPublisher eventPublisher
|
||||
|
||||
def setup() {
|
||||
itemProvider = Stub(ItemProvider)
|
||||
eventPublisher = Mock(EventPublisher)
|
||||
itemService = new ItemService(itemProvider, eventPublisher)
|
||||
}
|
||||
|
||||
def 'should return items sorted by name'() {
|
||||
given:
|
||||
def ids = ['offer-id', 'offer-id-2']
|
||||
itemProvider.getItems(ids) >> [new Item('offer-id-2', 'Zname'), new Item('offer-id', 'Aname')]
|
||||
|
||||
when:
|
||||
List<Item> items = itemService.getAllItemsSortedByName(ids)
|
||||
|
||||
then:
|
||||
items.collect { it.name } == ['Aname', 'Zname']
|
||||
}
|
||||
|
||||
def 'arguments constraints'() {
|
||||
itemProvider.getItems(['offer-id'])
|
||||
itemProvider.getItems(_) >> []
|
||||
itemProvider.getItems(*_) >> []
|
||||
itemProvider.getItems(!null) >> []
|
||||
itemProvider.getItems({ it.size > 0 }) >> []
|
||||
}
|
||||
|
||||
def 'should return different items on subsequent call'() {
|
||||
given:
|
||||
itemProvider.getItems(_) >>> [
|
||||
[],
|
||||
[new Item('1', 'name')],
|
||||
[new Item('2', 'name')]
|
||||
]
|
||||
|
||||
when: 'method is called for the first time'
|
||||
List<Item> items = itemService.getAllItemsSortedByName(['not-important'])
|
||||
|
||||
then: 'empty list is returned'
|
||||
items == []
|
||||
|
||||
when: 'method is called for the second time'
|
||||
items = itemService.getAllItemsSortedByName(['not-important'])
|
||||
|
||||
then: 'item with id=1 is returned'
|
||||
items == [new Item('1', 'name')]
|
||||
|
||||
when: 'method is called for the thirdtime'
|
||||
items = itemService.getAllItemsSortedByName(['not-important'])
|
||||
|
||||
then: 'item with id=2 is returned'
|
||||
items == [new Item('2', 'name')]
|
||||
}
|
||||
|
||||
def 'should throw ExternalItemProviderException when ItemProvider fails'() {
|
||||
given:
|
||||
itemProvider.getItems(_) >> { new RuntimeException()}
|
||||
|
||||
when:
|
||||
itemService.getAllItemsSortedByName([])
|
||||
|
||||
then:
|
||||
thrown(ExternalItemProviderException)
|
||||
}
|
||||
|
||||
def 'chaining response'() {
|
||||
itemProvider.getItems(_) >>> { new RuntimeException() } >> new SocketTimeoutException() >> [new Item('id', 'name')]
|
||||
}
|
||||
|
||||
def 'should return different items for different ids lists'() {
|
||||
given:
|
||||
def firstIds = ['first']
|
||||
def secondIds = ['second']
|
||||
itemProvider.getItems(firstIds) >> [new Item('first', 'Zname')]
|
||||
itemProvider.getItems(secondIds) >> [new Item('second', 'Aname')]
|
||||
|
||||
when:
|
||||
def firstItems = itemService.getAllItemsSortedByName(firstIds)
|
||||
def secondItems = itemService.getAllItemsSortedByName(secondIds)
|
||||
|
||||
then:
|
||||
firstItems.first().name == 'Zname'
|
||||
secondItems.first().name == 'Aname'
|
||||
}
|
||||
|
||||
def 'should publish events about new non-empty saved offers'() {
|
||||
given:
|
||||
def offerIds = ['', 'a', 'b']
|
||||
|
||||
when:
|
||||
itemService.saveItems(offerIds)
|
||||
|
||||
then:
|
||||
2 * eventPublisher.publish({ it != null && !it.isEmpty()})
|
||||
}
|
||||
|
||||
def 'should return items'() {
|
||||
given:
|
||||
itemProvider = Mock(ItemProvider)
|
||||
itemProvider.getItems(['item-id']) >> [new Item('item-id', 'name')]
|
||||
itemService = new ItemService(itemProvider, eventPublisher)
|
||||
|
||||
when:
|
||||
def items = itemService.getAllItemsSortedByName(['item-id'])
|
||||
|
||||
then:
|
||||
items == [new Item('item-id', 'name')]
|
||||
}
|
||||
|
||||
def 'should spy on EventPublisher method call'() {
|
||||
given:
|
||||
LoggingEventPublisher eventPublisher = Spy(LoggingEventPublisher)
|
||||
itemService = new ItemService(itemProvider, eventPublisher)
|
||||
|
||||
when:
|
||||
itemService.saveItems(['item-id'])
|
||||
|
||||
then:
|
||||
1 * eventPublisher.publish('item-id')
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import extensions.TimeoutTest
|
||||
import spock.lang.Issue
|
||||
|
||||
runner {
|
||||
|
||||
if (System.getenv("FILTER_STACKTRACE") == null) {
|
||||
filterStackTrace false
|
||||
}
|
||||
|
||||
report {
|
||||
issueNamePrefix 'Bug '
|
||||
issueUrlPrefix 'http://jira.org/issues/'
|
||||
}
|
||||
|
||||
optimizeRunOrder true
|
||||
|
||||
// exclude TimeoutTest
|
||||
// exclude {
|
||||
// baseClass TimeoutTest
|
||||
// annotation Issue
|
||||
// }
|
||||
|
||||
report {
|
||||
enabled true
|
||||
logFileDir '.'
|
||||
logFileName 'report.json'
|
||||
logFileSuffix new Date().format('yyyy-MM-dd')
|
||||
}
|
||||
|
||||
}
|
||||
3
testing-modules/junit-4/README.md
Normal file
3
testing-modules/junit-4/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Relevant Articles
|
||||
|
||||
- [Guide to JUnit 4 Rules](https://www.baeldung.com/junit-4-rules)
|
||||
31
testing-modules/junit-4/pom.xml
Normal file
31
testing-modules/junit-4/pom.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?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>
|
||||
<artifactId>junit-4</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>junit-4</name>
|
||||
<description>JUnit 4 Topics</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>pl.pragmatists</groupId>
|
||||
<artifactId>JUnitParams</artifactId>
|
||||
<version>${jUnitParams.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<jUnitParams.version>1.1.0</jUnitParams.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.junitparams;
|
||||
|
||||
public class SafeAdditionUtil {
|
||||
|
||||
public int safeAdd(int a, int b) {
|
||||
long result = ((long) a) + b;
|
||||
if (result > Integer.MAX_VALUE) {
|
||||
return Integer.MAX_VALUE;
|
||||
} else if (result < Integer.MIN_VALUE) {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
return (int) result;
|
||||
}
|
||||
|
||||
}
|
||||
13
testing-modules/junit-4/src/main/resources/logback.xml
Normal file
13
testing-modules/junit-4/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.baeldung.junitparams;
|
||||
|
||||
import junitparams.FileParameters;
|
||||
import junitparams.JUnitParamsRunner;
|
||||
import junitparams.Parameters;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(JUnitParamsRunner.class)
|
||||
public class SafeAdditionUtilUnitTest {
|
||||
|
||||
private SafeAdditionUtil serviceUnderTest = new SafeAdditionUtil();
|
||||
|
||||
@Test
|
||||
@Parameters({"1, 2, 3", "-10, 30, 20", "15, -5, 10", "-5, -10, -15"})
|
||||
public void whenWithAnnotationProvidedParams_thenSafeAdd(int a, int b, int expectedValue) {
|
||||
assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Parameters(method = "parametersToTestAdd")
|
||||
public void whenWithNamedMethod_thendSafeAdd(int a, int b, int expectedValue) {
|
||||
assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
|
||||
}
|
||||
|
||||
private Object[] parametersToTestAdd() {
|
||||
return new Object[]{new Object[]{1, 2, 3}, new Object[]{-10, 30, 20}, new Object[]{Integer.MAX_VALUE, 2, Integer.MAX_VALUE}, new Object[]{Integer.MIN_VALUE, -8, Integer.MIN_VALUE}};
|
||||
}
|
||||
|
||||
@Test
|
||||
@Parameters
|
||||
public void whenWithnoParam_thenLoadByNameSafeAdd(int a, int b, int expectedValue) {
|
||||
assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
|
||||
}
|
||||
|
||||
private Object[] parametersForWhenWithnoParam_thenLoadByNameSafeAdd() {
|
||||
return new Object[]{new Object[]{1, 2, 3}, new Object[]{-10, 30, 20}, new Object[]{Integer.MAX_VALUE, 2, Integer.MAX_VALUE}, new Object[]{Integer.MIN_VALUE, -8, Integer.MIN_VALUE}};
|
||||
}
|
||||
|
||||
@Test
|
||||
@Parameters(source = TestDataProvider.class)
|
||||
public void whenWithNamedClass_thenSafeAdd(int a, int b, int expectedValue) {
|
||||
assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
|
||||
}
|
||||
|
||||
@Test
|
||||
@FileParameters("src/test/resources/JunitParamsTestParameters.csv")
|
||||
public void whenWithCsvFile_thenSafeAdd(int a, int b, int expectedValue) {
|
||||
assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.junitparams;
|
||||
|
||||
public class TestDataProvider {
|
||||
|
||||
public static Object[] provideBasicData() {
|
||||
return new Object[]{new Object[]{1, 2, 3}, new Object[]{-10, 30, 20}, new Object[]{15, -5, 10}, new Object[]{-5, -10, -15}};
|
||||
}
|
||||
|
||||
public static Object[] provideEdgeCaseData() {
|
||||
return new Object[]{new Object[]{Integer.MAX_VALUE, 2, Integer.MAX_VALUE}, new Object[]{Integer.MIN_VALUE, -2, Integer.MIN_VALUE},};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.baeldung.rules;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MessageLogger implements TestRule {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MessageLogger.class);
|
||||
|
||||
private String message;
|
||||
|
||||
public MessageLogger(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(final Statement base, Description description) {
|
||||
return new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
try {
|
||||
LOG.info("Starting: {}", message);
|
||||
base.evaluate();
|
||||
} finally {
|
||||
LOG.info("Finished: {}", message);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.rules;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
|
||||
public class RuleChainUnitTest {
|
||||
|
||||
@Rule
|
||||
public RuleChain chain = RuleChain.outerRule(new MessageLogger("First rule"))
|
||||
.around(new MessageLogger("Second rule"))
|
||||
.around(new MessageLogger("Third rule"));
|
||||
|
||||
@Test
|
||||
public void givenRuleChain_whenTestRuns_thenChainOrderApplied() {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.baeldung.rules;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.isA;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.DisableOnDebug;
|
||||
import org.junit.rules.ErrorCollector;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.rules.TestName;
|
||||
import org.junit.rules.Timeout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RulesUnitTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RulesUnitTest.class);
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder tmpFolder = new TemporaryFolder();
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Rule
|
||||
public TestName name = new TestName();
|
||||
|
||||
@Rule
|
||||
public Timeout globalTimeout = Timeout.seconds(10);
|
||||
|
||||
@Rule
|
||||
public final ErrorCollector errorCollector = new ErrorCollector();
|
||||
|
||||
@Rule
|
||||
public DisableOnDebug disableTimeout = new DisableOnDebug(Timeout.seconds(30));
|
||||
|
||||
@Rule
|
||||
public TestMethodNameLogger testLogger = new TestMethodNameLogger();
|
||||
|
||||
@Test
|
||||
public void givenTempFolderRule_whenNewFile_thenFileIsCreated() throws IOException {
|
||||
File testFile = tmpFolder.newFile("test-file.txt");
|
||||
|
||||
assertTrue("The file should have been created: ", testFile.isFile());
|
||||
assertEquals("Temp folder and test file should match: ", tmpFolder.getRoot(), testFile.getParentFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIllegalArgument_whenExceptionThrown_thenMessageAndCauseMatches() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectCause(isA(NullPointerException.class));
|
||||
thrown.expectMessage("This is illegal");
|
||||
|
||||
throw new IllegalArgumentException("This is illegal", new NullPointerException());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAddition_whenPrintingTestName_thenTestNameIsDisplayed() {
|
||||
LOG.info("Executing: {}", name.getMethodName());
|
||||
assertEquals("givenAddition_whenPrintingTestName_thenTestNameIsDisplayed", name.getMethodName());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void givenLongRunningTest_whenTimout_thenTestFails() throws InterruptedException {
|
||||
TimeUnit.SECONDS.sleep(20);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void givenMultipleErrors_whenTestRuns_thenCollectorReportsErrors() {
|
||||
errorCollector.addError(new Throwable("First thing went wrong!"));
|
||||
errorCollector.addError(new Throwable("Another thing went wrong!"));
|
||||
|
||||
errorCollector.checkThat("Hello World", not(containsString("ERROR!")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.rules;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TestMethodNameLogger implements TestRule {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestMethodNameLogger.class);
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
logInfo("Before test", description);
|
||||
try {
|
||||
return new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
base.evaluate();
|
||||
}
|
||||
};
|
||||
} finally {
|
||||
logInfo("After test", description);
|
||||
}
|
||||
}
|
||||
|
||||
private void logInfo(String msg, Description description) {
|
||||
LOG.info(msg + description.getMethodName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.baeldung.rules;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Verifier;
|
||||
|
||||
public class VerifierRuleUnitTest {
|
||||
|
||||
private List<String> messageLog = new ArrayList<String>();
|
||||
|
||||
@Rule
|
||||
public Verifier verifier = new Verifier() {
|
||||
@Override
|
||||
public void verify() {
|
||||
assertFalse("Message Log is not Empty!", messageLog.isEmpty());
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void givenNewMessage_whenVerified_thenMessageLogNotEmpty() {
|
||||
// ...
|
||||
messageLog.add("There is a new message!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.runfromjava;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class FirstUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenThis_thenThat() {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSomething_thenSomething() {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSomethingElse_thenSomethingElse() {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.runfromjava;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({ FirstUnitTest.class, SecondUnitTest.class })
|
||||
public class MyTestSuite {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.baeldung.runfromjava;
|
||||
|
||||
import junit.extensions.ActiveTestSuite;
|
||||
import junit.extensions.RepeatedTest;
|
||||
import junit.framework.JUnit4TestAdapter;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
import org.junit.internal.TextListener;
|
||||
import org.junit.runner.JUnitCore;
|
||||
import org.junit.runner.Result;
|
||||
import org.junit.runner.notification.Failure;
|
||||
|
||||
public class RunJUnit4TestsFromJava {
|
||||
|
||||
public static void runOne() {
|
||||
JUnitCore junit = new JUnitCore();
|
||||
junit.addListener(new TextListener(System.out));
|
||||
junit.run(FirstUnitTest.class);
|
||||
}
|
||||
|
||||
public static void runAllClasses() {
|
||||
JUnitCore junit = new JUnitCore();
|
||||
junit.addListener(new TextListener(System.out));
|
||||
|
||||
Result result = junit.run(FirstUnitTest.class, SecondUnitTest.class);
|
||||
|
||||
for (Failure failure : result.getFailures()) {
|
||||
System.out.println(failure.toString());
|
||||
}
|
||||
|
||||
resultReport(result);
|
||||
}
|
||||
|
||||
public static void runSuiteOfClasses() {
|
||||
JUnitCore junit = new JUnitCore();
|
||||
junit.addListener(new TextListener(System.out));
|
||||
Result result = junit.run(MyTestSuite.class);
|
||||
|
||||
for (Failure failure : result.getFailures()) {
|
||||
System.out.println(failure.toString());
|
||||
}
|
||||
|
||||
resultReport(result);
|
||||
}
|
||||
|
||||
public static void runRepeated() {
|
||||
Test test = new JUnit4TestAdapter(SecondUnitTest.class);
|
||||
RepeatedTest repeatedTest = new RepeatedTest(test, 5);
|
||||
|
||||
JUnitCore junit = new JUnitCore();
|
||||
junit.addListener(new TextListener(System.out));
|
||||
|
||||
junit.run(repeatedTest);
|
||||
}
|
||||
|
||||
public static void runRepeatedSuite() {
|
||||
TestSuite mySuite = new ActiveTestSuite();
|
||||
|
||||
JUnitCore junit = new JUnitCore();
|
||||
junit.addListener(new TextListener(System.out));
|
||||
|
||||
mySuite.addTest(new RepeatedTest(new JUnit4TestAdapter(FirstUnitTest.class), 5));
|
||||
mySuite.addTest(new RepeatedTest(new JUnit4TestAdapter(SecondUnitTest.class), 3));
|
||||
|
||||
junit.run(mySuite);
|
||||
}
|
||||
|
||||
public static void resultReport(Result result) {
|
||||
System.out.println("Finished. Result: Failures: " +
|
||||
result.getFailureCount() + ". Ignored: " +
|
||||
result.getIgnoreCount() + ". Tests run: " +
|
||||
result.getRunCount() + ". Time: " +
|
||||
result.getRunTime() + "ms.");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("\nRunning one test class:");
|
||||
runOne();
|
||||
|
||||
System.out.println("\nRunning all test classes:");
|
||||
runAllClasses();
|
||||
|
||||
System.out.println("\nRunning a suite of test classes:");
|
||||
runSuiteOfClasses();
|
||||
|
||||
System.out.println("\nRunning repeated tests:");
|
||||
runRepeated();
|
||||
|
||||
System.out.println("\nRunning repeated suite tests:");
|
||||
runRepeatedSuite();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.runfromjava;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class SecondUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenSomething_thenSomething() {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whensomethingElse_thenSomethingElse() {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
1,2,3
|
||||
-10, 30, 20
|
||||
15, -5, 10
|
||||
-5, -10, -15
|
||||
|
4
testing-modules/junit-5-advanced/README.md
Normal file
4
testing-modules/junit-5-advanced/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
## Relevant Articles:
|
||||
|
||||
- [JUnit 5 TestWatcher API](https://www.baeldung.com/junit-testwatcher)
|
||||
- [JUnit Custom Display Name Generator API](https://www.baeldung.com/junit-custom-display-name-generator)
|
||||
52
testing-modules/junit-5-advanced/pom.xml
Normal file
52
testing-modules/junit-5-advanced/pom.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<?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>
|
||||
<artifactId>junit-5-advanced</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>junit-5-advanced</name>
|
||||
<description>Advanced JUnit 5 Topics</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
<version>${junit.vintage.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<properties>
|
||||
<junit-jupiter.version>5.4.2</junit-jupiter.version>
|
||||
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
||||
<junit.vintage.version>5.4.2</junit.vintage.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.failure_vs_error;
|
||||
|
||||
/**
|
||||
* @author paullatzelsperger
|
||||
* @since 2019-07-17
|
||||
*/
|
||||
public class SimpleCalculator {
|
||||
|
||||
public static double divideNumbers(double dividend, double divisor) {
|
||||
if (divisor == 0) {
|
||||
throw new ArithmeticException("Division by zero!");
|
||||
}
|
||||
return dividend / divisor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.junit5.testinstance;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Tweet implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String id;
|
||||
private String content;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.junit5.testinstance;
|
||||
|
||||
public class TweetException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public TweetException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.junit5.testinstance;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
public class TweetSerializer {
|
||||
|
||||
private static final int MAX_TWEET_SIZE = 1000;
|
||||
private static final int MIN_TWEET_SIZE = 150;
|
||||
private final Tweet tweet;
|
||||
|
||||
public TweetSerializer(Tweet tweet) {
|
||||
this.tweet = tweet;
|
||||
}
|
||||
|
||||
public byte[] serialize() throws IOException {
|
||||
byte[] tweetContent = serializeTweet();
|
||||
int totalLength = tweetContent.length;
|
||||
validateSizeOfTweet(totalLength);
|
||||
return tweetContent;
|
||||
}
|
||||
|
||||
private void validateSizeOfTweet(int tweetSize) {
|
||||
if (tweetSize > MAX_TWEET_SIZE) {
|
||||
throw new TweetException("Tweet is too large");
|
||||
}
|
||||
if (tweetSize < MIN_TWEET_SIZE) {
|
||||
throw new TweetException("Tweet is too small");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] serializeTweet() throws IOException {
|
||||
try (ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
|
||||
ObjectOutputStream objectStream = new ObjectOutputStream(arrayOutputStream)) {
|
||||
objectStream.writeObject(tweet);
|
||||
return arrayOutputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.baeldung.displayname;
|
||||
|
||||
import org.junit.jupiter.api.DisplayNameGeneration;
|
||||
import org.junit.jupiter.api.DisplayNameGenerator;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@DisplayNameGeneration(DisplayNameGeneratorUnitTest.ReplaceCamelCase.class)
|
||||
class DisplayNameGeneratorUnitTest {
|
||||
|
||||
@Test
|
||||
void camelCaseName() {
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayNameGeneration(DisplayNameGeneratorUnitTest.IndicativeSentences.class)
|
||||
class ANumberIsFizz {
|
||||
@Test
|
||||
void ifItIsDivisibleByThree() {
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "Number {0} is fizz.")
|
||||
@ValueSource(ints = { 3, 12, 18 })
|
||||
void ifItIsOneOfTheFollowingNumbers(int number) {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayNameGeneration(DisplayNameGeneratorUnitTest.IndicativeSentences.class)
|
||||
class ANumberIsBuzz {
|
||||
@Test
|
||||
void ifItIsDivisibleByFive() {
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "Number {0} is buzz.")
|
||||
@ValueSource(ints = { 5, 10, 20 })
|
||||
void ifItIsOneOfTheFollowingNumbers(int number) {
|
||||
}
|
||||
}
|
||||
|
||||
static class IndicativeSentences extends ReplaceCamelCase {
|
||||
@Override
|
||||
public String generateDisplayNameForNestedClass(Class<?> nestedClass) {
|
||||
return super.generateDisplayNameForNestedClass(nestedClass) + "...";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) {
|
||||
return replaceCamelCase(testClass.getSimpleName() + " " + testMethod.getName()) + ".";
|
||||
}
|
||||
}
|
||||
|
||||
static class ReplaceCamelCase extends DisplayNameGenerator.Standard {
|
||||
@Override
|
||||
public String generateDisplayNameForClass(Class<?> testClass) {
|
||||
return replaceCamelCase(super.generateDisplayNameForClass(testClass));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateDisplayNameForNestedClass(Class<?> nestedClass) {
|
||||
return replaceCamelCase(super.generateDisplayNameForNestedClass(nestedClass));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) {
|
||||
return this.replaceCamelCase(testMethod.getName()) + DisplayNameGenerator.parameterTypesAsString(testMethod);
|
||||
}
|
||||
|
||||
String replaceCamelCase(String camelCase) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append(camelCase.charAt(0));
|
||||
for (int i=1; i<camelCase.length(); i++) {
|
||||
if (Character.isUpperCase(camelCase.charAt(i))) {
|
||||
result.append(' ');
|
||||
result.append(Character.toLowerCase(camelCase.charAt(i)));
|
||||
} else {
|
||||
result.append(camelCase.charAt(i));
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.displayname;
|
||||
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
|
||||
class ReplaceUnderscoresGeneratorUnitTest {
|
||||
|
||||
@Nested
|
||||
class when_doing_something {
|
||||
|
||||
@Test
|
||||
void then_something_should_happen() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("@DisplayName takes precedence over generation")
|
||||
void override_generator() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.baeldung.extensions.testwatcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TestResultLoggerExtension implements TestWatcher, AfterAllCallback {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestResultLoggerExtension.class);
|
||||
|
||||
private List<TestResultStatus> testResultsStatus = new ArrayList<>();
|
||||
|
||||
private enum TestResultStatus {
|
||||
SUCCESSFUL, ABORTED, FAILED, DISABLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testDisabled(ExtensionContext context, Optional<String> reason) {
|
||||
LOG.info("Test Disabled for test {}: with reason :- {}", context.getDisplayName(), reason.orElse("No reason"));
|
||||
|
||||
testResultsStatus.add(TestResultStatus.DISABLED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testSuccessful(ExtensionContext context) {
|
||||
LOG.info("Test Successful for test {}: ", context.getDisplayName());
|
||||
|
||||
testResultsStatus.add(TestResultStatus.SUCCESSFUL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testAborted(ExtensionContext context, Throwable cause) {
|
||||
LOG.info("Test Aborted for test {}: ", context.getDisplayName());
|
||||
|
||||
testResultsStatus.add(TestResultStatus.ABORTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
LOG.info("Test Aborted for test {}: ", context.getDisplayName());
|
||||
|
||||
testResultsStatus.add(TestResultStatus.FAILED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) throws Exception {
|
||||
Map<TestResultStatus, Long> summary = testResultsStatus.stream()
|
||||
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
|
||||
|
||||
LOG.info("Test result summary for {} {}", context.getDisplayName(), summary.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.extensions.testwatcher;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
@ExtendWith(TestResultLoggerExtension.class)
|
||||
class TestWatcherAPIUnitTest {
|
||||
|
||||
@Test
|
||||
void givenFalseIsTrue_whenTestAbortedThenCaptureResult() {
|
||||
Assumptions.assumeTrue(false);
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
void givenTrueIsTrue_whenTestDisabledThenCaptureResult() {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenTrueIsTrue_whenTestAbortedThenCaptureResult() {
|
||||
Assumptions.assumeTrue(true);
|
||||
}
|
||||
|
||||
@Disabled("This test is disabled")
|
||||
@Test
|
||||
void givenFailure_whenTestDisabledWithReason_ThenCaptureResult() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.failure_vs_error;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author paullatzelsperger
|
||||
* @since 2019-07-17
|
||||
*/
|
||||
class SimpleCalculatorUnitTest {
|
||||
|
||||
@Test
|
||||
void divideNumbers() {
|
||||
double result = SimpleCalculator.divideNumbers(6, 3);
|
||||
assertEquals(2, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("test is expected to fail, disabled so that CI build still goes through")
|
||||
void divideNumbers_failure() {
|
||||
double result = SimpleCalculator.divideNumbers(6, 3);
|
||||
assertEquals(15, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("test is expected to raise an error, disabled so that CI build still goes through")
|
||||
void divideNumbers_error() {
|
||||
SimpleCalculator.divideNumbers(10, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.junit5.testinstance;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class AdditionUnitTest {
|
||||
|
||||
private int sum = 1;
|
||||
|
||||
@Test
|
||||
void addingTwoToSumReturnsThree() {
|
||||
sum += 2;
|
||||
assertEquals(3, sum);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addingThreeToSumReturnsFour() {
|
||||
sum += 3;
|
||||
assertEquals(4, sum);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.junit5.testinstance;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
|
||||
@TestMethodOrder(OrderAnnotation.class)
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class OrderUnitTest {
|
||||
|
||||
private int sum;
|
||||
|
||||
@BeforeAll
|
||||
void init() {
|
||||
sum = 1;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
void firstTest() {
|
||||
sum += 2;
|
||||
assertEquals(3, sum);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
void secondTest() {
|
||||
sum += 3;
|
||||
assertEquals(6, sum);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.baeldung.junit5.testinstance;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
public class TweetSerializerJUnit4UnitTest {
|
||||
|
||||
private static String largeContent;
|
||||
private static String content;
|
||||
private static String smallContent;
|
||||
|
||||
private static Tweet tweet;
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpFixture() throws IOException {
|
||||
content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit";
|
||||
smallContent = "Lorem ipsum dolor";
|
||||
largeContent = new String(Files.readAllBytes(Paths.get("src/test/resources/lorem-ipsum.txt")));
|
||||
tweet = new Tweet();
|
||||
tweet.setId("AX1346");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializerThrowsExceptionWhenMessageIsTooLarge() throws IOException {
|
||||
tweet.setContent(largeContent);
|
||||
|
||||
expectedException.expect(TweetException.class);
|
||||
expectedException.expectMessage("Tweet is too large");
|
||||
|
||||
new TweetSerializer(tweet).serialize();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializerThrowsExceptionWhenMessageIsTooSmall() throws IOException {
|
||||
tweet.setContent(smallContent);
|
||||
|
||||
expectedException.expect(TweetException.class);
|
||||
expectedException.expectMessage("Tweet is too small");
|
||||
|
||||
new TweetSerializer(tweet).serialize();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializeTweet() throws IOException {
|
||||
tweet.setContent(content);
|
||||
byte[] content = new TweetSerializer(tweet).serialize();
|
||||
assertThat(content, is(notNullValue()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.baeldung.junit5.testinstance;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class TweetSerializerUnitTest {
|
||||
|
||||
private String largeContent;
|
||||
private String content;
|
||||
private String smallContent;
|
||||
|
||||
private Tweet tweet;
|
||||
|
||||
@BeforeAll
|
||||
void setUpFixture() throws IOException {
|
||||
content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit";
|
||||
smallContent = "Lorem ipsum dolor";
|
||||
largeContent = new String(Files.readAllBytes(Paths.get("src/test/resources/lorem-ipsum.txt")));
|
||||
tweet = new Tweet();
|
||||
tweet.setId("AX1346");
|
||||
}
|
||||
|
||||
@Test
|
||||
void serializerThrowsExceptionWhenMessageIsTooLarge() throws IOException {
|
||||
tweet.setContent(largeContent);
|
||||
|
||||
TweetException tweetException = assertThrows(TweetException.class, () -> new TweetSerializer(tweet).serialize());
|
||||
assertThat(tweetException.getMessage(), is(equalTo("Tweet is too large")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void serializerThrowsExceptionWhenMessageIsTooSmall() throws IOException {
|
||||
tweet.setContent(smallContent);
|
||||
|
||||
TweetException tweetException = assertThrows(TweetException.class, () -> new TweetSerializer(tweet).serialize());
|
||||
assertThat(tweetException.getMessage(), is(equalTo("Tweet is too small")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void serializeTweet() throws IOException {
|
||||
tweet.setContent(content);
|
||||
byte[] content = new TweetSerializer(tweet).serialize();
|
||||
assertThat(content, is(notNullValue()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
11
testing-modules/junit-5-basics/README.md
Normal file
11
testing-modules/junit-5-basics/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
### Relevant Articles:
|
||||
- [A Guide to JUnit 5](http://www.baeldung.com/junit-5)
|
||||
- [JUnit5 @RunWith](http://www.baeldung.com/junit-5-runwith)
|
||||
- [Get the Path of the /src/test/resources Directory in JUnit](https://www.baeldung.com/junit-src-test-resources-directory-path)
|
||||
- [Tagging and Filtering JUnit Tests](https://www.baeldung.com/junit-filtering-tests)
|
||||
- [JUnit 5 Temporary Directory Support](https://www.baeldung.com/junit-5-temporary-directory)
|
||||
- [@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll](http://www.baeldung.com/junit-before-beforeclass-beforeeach-beforeall)
|
||||
- [JUnit 5 @Test Annotation](http://www.baeldung.com/junit-5-test-annotation)
|
||||
- [Migrating from JUnit 4 to JUnit 5](http://www.baeldung.com/junit-5-migration)
|
||||
- [Assert an Exception is Thrown in JUnit 4 and 5](http://www.baeldung.com/junit-assert-exception)
|
||||
- [The Difference Between Failure and Error in JUnit](https://www.baeldung.com/junit-failure-vs-error)
|
||||
160
testing-modules/junit-5-basics/pom.xml
Normal file
160
testing-modules/junit-5-basics/pom.xml
Normal file
@@ -0,0 +1,160 @@
|
||||
<?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>
|
||||
<artifactId>junit-5-basics</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>junit-5-basics</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>
|
||||
|
||||
<dependencies>
|
||||
<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.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-migrationsupport</artifactId>
|
||||
<version>${junit.vintage.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2.version}</version>
|
||||
</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>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/test/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>filtering</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
|
||||
<configuration>
|
||||
<excludes>
|
||||
**/*IntegrationTest.java
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>category</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<groups>com.baeldung.categories.UnitTest</groups>
|
||||
<excludedGroups>com.baeldung.categories.IntegrationTest</excludedGroups>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>tags</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<groups>UnitTest</groups>
|
||||
<excludedGroups>IntegrationTest</excludedGroups>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<junit.vintage.version>5.4.2</junit.vintage.version>
|
||||
<junit-platform.version>1.2.0</junit-platform.version>
|
||||
<junit-jupiter.version>5.4.2</junit-jupiter.version>
|
||||
<spring.version>5.0.6.RELEASE</spring.version>
|
||||
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.failure_vs_error;
|
||||
|
||||
/**
|
||||
* @author paullatzelsperger
|
||||
* @since 2019-07-17
|
||||
*/
|
||||
public class SimpleCalculator {
|
||||
|
||||
public static double divideNumbers(double dividend, double divisor) {
|
||||
if (divisor == 0) {
|
||||
throw new ArithmeticException("Division by zero!");
|
||||
}
|
||||
return dividend / divisor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.junit.tags.example;
|
||||
|
||||
public class Employee {
|
||||
private int id;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String address;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(final String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(final String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(final String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.baeldung.junit.tags.example;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Repository
|
||||
public class EmployeeDAO {
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||
|
||||
private SimpleJdbcInsert simpleJdbcInsert;
|
||||
|
||||
@Autowired
|
||||
public void setDataSource(final DataSource dataSource) {
|
||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
|
||||
namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
|
||||
simpleJdbcInsert = new SimpleJdbcInsert(dataSource).withTableName("EMPLOYEE");
|
||||
|
||||
}
|
||||
|
||||
public int getCountOfEmployees() {
|
||||
return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM EMPLOYEE", Integer.class);
|
||||
}
|
||||
|
||||
public List<Employee> getAllEmployees() {
|
||||
return jdbcTemplate.query("SELECT * FROM EMPLOYEE", new EmployeeRowMapper());
|
||||
}
|
||||
|
||||
public int addEmplyee(final int id) {
|
||||
return jdbcTemplate.update("INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)", id, "Bill", "Gates", "USA");
|
||||
}
|
||||
|
||||
public int addEmplyeeUsingSimpelJdbcInsert(final Employee emp) {
|
||||
final Map<String, Object> parameters = new HashMap<String, Object>();
|
||||
parameters.put("ID", emp.getId());
|
||||
parameters.put("FIRST_NAME", emp.getFirstName());
|
||||
parameters.put("LAST_NAME", emp.getLastName());
|
||||
parameters.put("ADDRESS", emp.getAddress());
|
||||
|
||||
return simpleJdbcInsert.execute(parameters);
|
||||
}
|
||||
|
||||
// for testing
|
||||
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.junit.tags.example;
|
||||
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class EmployeeRowMapper implements RowMapper<Employee> {
|
||||
|
||||
@Override
|
||||
public Employee mapRow(final ResultSet rs, final int rowNum) throws SQLException {
|
||||
final Employee employee = new Employee();
|
||||
|
||||
employee.setId(rs.getInt("ID"));
|
||||
employee.setFirstName(rs.getString("FIRST_NAME"));
|
||||
employee.setLastName(rs.getString("LAST_NAME"));
|
||||
employee.setAddress(rs.getString("ADDRESS"));
|
||||
|
||||
return employee;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.junit.tags.example;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan("com.baeldung.junit.tags.example")
|
||||
public class SpringJdbcConfig {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).addScript("classpath:jdbc/schema.sql").addScript("classpath:jdbc/test-data.sql").build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.junit5;
|
||||
|
||||
public class Greetings {
|
||||
|
||||
public static String sayHello() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.junit5.bean;
|
||||
|
||||
/**
|
||||
* Bean that contains utility methods to work with numbers.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*
|
||||
*/
|
||||
public class NumbersBean {
|
||||
|
||||
/**
|
||||
* Returns true if a number is even, false otherwise.
|
||||
*
|
||||
* @param number
|
||||
* the number to check
|
||||
* @return true if the argument is even, false otherwise
|
||||
*/
|
||||
public boolean isNumberEven(int number) {
|
||||
return number % 2 == 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE EMPLOYEE
|
||||
(
|
||||
ID int NOT NULL PRIMARY KEY,
|
||||
FIRST_NAME varchar(255),
|
||||
LAST_NAME varchar(255),
|
||||
ADDRESS varchar(255),
|
||||
);
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"
|
||||
>
|
||||
|
||||
<bean id="employeeDao" class="org.baeldung.jdbc.EmployeeDAO">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
|
||||
<property name="driverClassName" value="${jdbc.driverClassName}"/>
|
||||
<property name="url" value="${jdbc.url}"/>
|
||||
<property name="username" value="${jdbc.username}"/>
|
||||
<property name="password" value="${jdbc.password}"/>
|
||||
</bean>
|
||||
|
||||
<context:property-placeholder location="jdbc.properties"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,7 @@
|
||||
INSERT INTO EMPLOYEE VALUES (1, 'James', 'Gosling', 'Canada');
|
||||
|
||||
INSERT INTO EMPLOYEE VALUES (2, 'Donald', 'Knuth', 'USA');
|
||||
|
||||
INSERT INTO EMPLOYEE VALUES (3, 'Linus', 'Torvalds', 'Finland');
|
||||
|
||||
INSERT INTO EMPLOYEE VALUES (4, 'Dennis', 'Ritchie', 'USA');
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.baeldung;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenModifyMapDuringIteration_thenThrowExecption() {
|
||||
Map<Integer, String> hashmap = new HashMap<>();
|
||||
hashmap.put(1, "One");
|
||||
hashmap.put(2, "Two");
|
||||
|
||||
Executable executable = () -> hashmap.forEach((key, value) -> hashmap.remove(1));
|
||||
assertThrows(ConcurrentModificationException.class, executable);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user