New artifacts for BAEL-1081. (#2392)

* New artifacts for BAEL-1081.

* Consolidate code to new package.
This commit is contained in:
Makoto Go 2017-08-10 08:27:27 -05:00 committed by Eugen
parent 71ef6b2a43
commit 146b633bac
6 changed files with 391 additions and 4 deletions

View File

@ -3,7 +3,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<!-- NOT NEEDED - JSP <groupId>com.baeldung</groupId>-->
<artifactId>junit5</artifactId>
<version>1.0-SNAPSHOT</version>
@ -19,9 +19,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<junit.jupiter.version>5.0.0-M5</junit.jupiter.version>
<junit.platform.version>1.0.0-M5</junit.platform.version>
<junit.vintage.version>4.12.0-M5</junit.vintage.version>
<junit.jupiter.version>5.0.0-RC2</junit.jupiter.version>
<junit.platform.version>1.0.0-RC2</junit.platform.version>
<junit.vintage.version>4.12.0-RC2</junit.vintage.version>
<log4j2.version>2.8.2</log4j2.version>
<h2.version>1.4.196</h2.version>

View File

@ -0,0 +1,50 @@
package com.baeldung.param;
import java.util.Random;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
public class InvalidPersonParameterResolver implements ParameterResolver {
/**
* The "bad" (invalid) data for testing purposes has to go somewhere, right?
*/
public static Person[] INVALID_PERSONS = {
new Person().setId(1L).setLastName("Ad_ams").setFirstName("Jill,"),
new Person().setId(2L).setLastName(",Baker").setFirstName(""),
new Person().setId(3L).setLastName(null).setFirstName(null),
new Person().setId(4L).setLastName("Daniel&").setFirstName("{Joseph}"),
new Person().setId(5L).setLastName("").setFirstName("English, Jane"),
new Person()/* .setId(6L).setLastName("Fontana").setFirstName("Enrique") */,
// TODO: ADD MORE DATA HERE
};
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
Object ret = null;
//
// Return a random, valid Person object if Person.class is the type of Parameter
/// to be resolved. Otherwise return null.
if (parameterContext.getParameter().getType() == Person.class) {
ret = INVALID_PERSONS[new Random().nextInt(INVALID_PERSONS.length)];
}
return ret;
}
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
boolean ret = false;
//
// If the Parameter.type == Person.class, then we support it, otherwise, get outta here!
if (parameterContext.getParameter().getType() == Person.class) {
ret = true;
}
return ret;
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.param;
/**
* Very simple Person entity.
* Use the Fluent-style interface to set properties.
*
* @author J Steven Perry
*
*/
public class Person {
private Long id;
private String lastName;
private String firstName;
public Long getId() {
return id;
}
public Person setId(Long id) {
this.id = id;
return this;
}
public String getLastName() {
return lastName;
}
public Person setLastName(String lastName) {
this.lastName = lastName;
return this;
}
public String getFirstName() {
return firstName;
}
public Person setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
}

View File

@ -0,0 +1,142 @@
package com.baeldung.param;
import java.util.Arrays;
/**
* Somewhat contrived validation class to illustrate unit test
* concepts.
*
* @author J Steven Perry
*
*/
public class PersonValidator {
/**
* Contrived checked exception to illustrate one possible
* way to handle validation errors (via a checked exception).
*
* @author J Steven Perry
*
*/
public static class ValidationException extends Exception {
/**
*
*/
private static final long serialVersionUID = -134518049431883102L;
// Probably should implement some more constructors, but don't want
/// to tarnish the lesson...
/**
* The one and only way to create this checked exception.
*
* @param message
* The message accompanying the exception. Should be meaningful.
*/
public ValidationException(String message) {
super(message);
}
}
private static final String[] ILLEGAL_NAME_CHARACTERS = {
",",
"_",
"{",
"}",
"!"
};
/**
* Validate the first name of the specified Person object.
*
* @param person
* The Person object to validate.
*
* @return - returns true if the specified Person is valid
*
* @throws ValidationException
* - this Exception is thrown if any kind of validation error occurs.
*/
public static boolean validateFirstName(Person person) throws ValidationException {
boolean ret = true;
// The validation rules go here.
// Naive: use simple ifs
if (person == null) {
throw new ValidationException("Person is null (not allowed)!");
}
if (person.getFirstName() == null) {
throw new ValidationException("Person FirstName is null (not allowed)!");
}
if (person.getFirstName().isEmpty()) {
throw new ValidationException("Person FirstName is an empty String (not allowed)!");
}
if (!isStringValid(person.getFirstName(), ILLEGAL_NAME_CHARACTERS)) {
throw new ValidationException(
"Person FirstName (" + person.getFirstName() + ") may not contain any of the following characters: "
+ Arrays.toString(ILLEGAL_NAME_CHARACTERS)
+ "!");
}
return ret;
}
/**
* Validate the last name of the specified Person object. Looks the same as first
* name? Look closer. Just kidding. It's the same. But real world code can (and will) diverge.
*
* @param person
* The Person object to validate.
*
* @return - returns true if the specified Person is valid
*
* @throws ValidationException
* - this Exception is thrown if any kind of validation error occurs.
*/
public static boolean validateLastName(Person person) throws ValidationException {
boolean ret = true;
// The validation rules go here.
// Naive: use simple ifs
if (person == null) {
throw new ValidationException("Person is null (not allowed)!");
}
if (person.getFirstName() == null) {
throw new ValidationException("Person FirstName is null (not allowed)!");
}
if (person.getFirstName().isEmpty()) {
throw new ValidationException("Person FirstName is an empty String (not allowed)!");
}
if (!isStringValid(person.getFirstName(), ILLEGAL_NAME_CHARACTERS)) {
throw new ValidationException(
"Person LastName (" + person.getLastName() + ") may not contain any of the following characters: "
+ Arrays.toString(ILLEGAL_NAME_CHARACTERS)
+ "!");
}
return ret;
}
/**
* Validates the specified name. If it contains any of the illegalCharacters,
* this method returns false (indicating the name is illegal). Otherwise it returns true.
*
* @param candidate
* The candidate String to validate
*
* @param illegalCharacters
* The characters the String is not allowed to have
*
* @return - boolean - true if the name is valid, false otherwise.
*/
private static boolean isStringValid(String candidate, String[] illegalCharacters) {
boolean ret = true;
for (String illegalChar : illegalCharacters) {
if (candidate.contains(illegalChar)) {
ret = false;
break;
}
}
return ret;
}
}

View File

@ -0,0 +1,102 @@
package com.baeldung.param;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
@RunWith(JUnitPlatform.class)
@DisplayName("Testing PersonValidator")
public class PersonValidatorTest {
/**
* Nested class, uses ExtendWith
* {@link com.baeldung.param.ValidPersonParameterResolver ValidPersonParameterResolver}
* to feed Test methods with "good" data.
*/
@Nested
@DisplayName("When using Valid data")
@ExtendWith(ValidPersonParameterResolver.class)
public class ValidData {
/**
* Repeat the test ten times, that way we have a good shot at
* running all of the data through at least once.
*
* @param person
* A valid Person object to validate.
*/
@RepeatedTest(value = 10)
@DisplayName("All first names are valid")
public void validateFirstName(Person person) {
try {
assertTrue(PersonValidator.validateFirstName(person));
} catch (PersonValidator.ValidationException e) {
fail("Exception not expected: " + e.getLocalizedMessage());
}
}
/**
* Repeat the test ten times, that way we have a good shot at
* running all of the data through at least once.
*
* @param person
* A valid Person object to validate.
*/
@RepeatedTest(value = 10)
@DisplayName("All last names are valid")
public void validateLastName(Person person) {
try {
assertTrue(PersonValidator.validateLastName(person));
} catch (PersonValidator.ValidationException e) {
fail("Exception not expected: " + e.getLocalizedMessage());
}
}
}
/**
* Nested class, uses ExtendWith
* {@link com.baeldung.param.InvalidPersonParameterResolver InvalidPersonParameterResolver}
* to feed Test methods with "bad" data.
*/
@Nested
@DisplayName("When using Invalid data")
@ExtendWith(InvalidPersonParameterResolver.class)
public class InvalidData {
/**
* Repeat the test ten times, that way we have a good shot at
* running all of the data through at least once.
*
* @param person
* An invalid Person object to validate.
*/
@RepeatedTest(value = 10)
@DisplayName("All first names are invalid")
public void validateFirstName(Person person) {
assertThrows(PersonValidator.ValidationException.class, () -> PersonValidator.validateFirstName(person));
}
/**
* Repeat the test ten times, that way we have a good shot at
* running all of the data through at least once.
*
* @param person
* An invalid Person object to validate.
*/
@RepeatedTest(value = 10)
@DisplayName("All first names are invalid")
public void validateLastName(Person person) {
assertThrows(PersonValidator.ValidationException.class, () -> PersonValidator.validateLastName(person));
}
}
}

View File

@ -0,0 +1,50 @@
package com.baeldung.param;
import java.util.Random;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
public class ValidPersonParameterResolver implements ParameterResolver {
/**
* The "good" (valid) data for testing purposes has to go somewhere, right?
*/
public static Person[] VALID_PERSONS = {
new Person().setId(1L).setLastName("Adams").setFirstName("Jill"),
new Person().setId(2L).setLastName("Baker").setFirstName("James"),
new Person().setId(3L).setLastName("Carter").setFirstName("Samanta"),
new Person().setId(4L).setLastName("Daniels").setFirstName("Joseph"),
new Person().setId(5L).setLastName("English").setFirstName("Jane"),
new Person().setId(6L).setLastName("Fontana").setFirstName("Enrique"),
// TODO: ADD MORE DATA HERE
};
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
Object ret = null;
//
// Return a random, valid Person object if Person.class is the type of Parameter
/// to be resolved. Otherwise return null.
if (parameterContext.getParameter().getType() == Person.class) {
ret = VALID_PERSONS[new Random().nextInt(VALID_PERSONS.length)];
}
return ret;
}
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
boolean ret = false;
//
// If the Parameter.type == Person.class, then we support it, otherwise, get outta here!
if (parameterContext.getParameter().getType() == Person.class) {
ret = true;
}
return ret;
}
}