Bael 7436 (#15550)
* BAEL-7436: Initial Unit Tests * BAEL-7436: Added an Example with Service * BAEL-7436: Cleanup and test fixes * BAEL-7436: Test rename * BAEL-7436: Cleanup * BAEL-7436: Fix pom * BAEL-7436: Test rename
This commit is contained in:
parent
6114e0534f
commit
61e5d8cd76
|
@ -14,4 +14,20 @@
|
|||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${apache.commons.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<apache.commons.version>3.14.0</apache.commons.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
public class Address implements Cloneable {
|
||||
|
||||
private ZipCode zipCode;
|
||||
|
||||
public ZipCode getZipCode() {
|
||||
return zipCode;
|
||||
}
|
||||
|
||||
public void setZipCode(ZipCode zipCode) {
|
||||
this.zipCode = zipCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Address clone() {
|
||||
Address address;
|
||||
try {
|
||||
address = ((Address) super.clone());
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
zipCode = zipCode.clone();
|
||||
return address;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Delivery {
|
||||
|
||||
private String message;
|
||||
|
||||
public Delivery(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Delivery delivery = (Delivery) o;
|
||||
|
||||
return Objects.equals(message, delivery.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return message != null ? message.hashCode() : 0;
|
||||
}
|
||||
|
||||
public static Delivery freeDelivery() {
|
||||
return new Delivery("Free delivery");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
public interface DeliveryService {
|
||||
|
||||
Delivery calculateDeliveryForPerson(Long id);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
public class Person implements Cloneable {
|
||||
|
||||
private Address address;
|
||||
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Person clone() {
|
||||
Person person;
|
||||
try {
|
||||
person = (Person) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
address = address.clone();
|
||||
return person;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
public class ZipCode implements Cloneable {
|
||||
|
||||
private String code;
|
||||
|
||||
public ZipCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ZipCode clone() {
|
||||
try {
|
||||
return (ZipCode) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
import static java.util.Objects.requireNonNullElse;
|
||||
import static java.util.Objects.requireNonNullElseGet;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
||||
class NullConversionUnitTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsProvider.class)
|
||||
void givenIfWhenNotNullThenReturnsDefault(String givenValue, String defaultValue) {
|
||||
String actual = defaultValue;
|
||||
if (givenValue != null) {
|
||||
actual = givenValue;
|
||||
}
|
||||
assertDefaultConversion(givenValue, defaultValue, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsSupplierProvider.class)
|
||||
void givenIfWhenNotNullThenReturnsDefault(String givenValue, String expected,
|
||||
Supplier<String> expensiveSupplier) {
|
||||
String actual;
|
||||
if (givenValue != null) {
|
||||
actual = givenValue;
|
||||
} else {
|
||||
actual = expensiveSupplier.get();
|
||||
}
|
||||
assertDefaultConversion(givenValue, expected, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsProvider.class)
|
||||
void givenTernaryWhenNotNullThenReturnsDefault(String givenValue, String defaultValue) {
|
||||
String actual = givenValue != null ? givenValue : defaultValue;
|
||||
assertDefaultConversion(givenValue, defaultValue, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsSupplierProvider.class)
|
||||
void givenLazyTernaryWhenNotNullThenReturnsDefault(String givenValue, String expected,
|
||||
Supplier<String> expensiveSupplier) {
|
||||
String actual = givenValue != null ? givenValue : expensiveSupplier.get();
|
||||
assertDefaultConversion(givenValue, expected, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsProvider.class)
|
||||
void givenObjectsWhenNotNullThenReturnsDefault(String givenValue, String defaultValue) {
|
||||
String actual = requireNonNullElse(givenValue, defaultValue);
|
||||
assertDefaultConversion(givenValue, defaultValue, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsSupplierProvider.class)
|
||||
void givenLazyObjectsWhenNotNullThenReturnsDefault(String givenValue, String expected,
|
||||
Supplier<String> expensiveSupplier) {
|
||||
String actual = requireNonNullElseGet(givenValue, expensiveSupplier);
|
||||
assertDefaultConversion(givenValue, expected, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsProvider.class)
|
||||
void givenOptionalWhenNotNullThenReturnsDefault(String givenValue, String defaultValue) {
|
||||
String actual = Optional.ofNullable(givenValue).orElse(defaultValue);
|
||||
assertDefaultConversion(givenValue, defaultValue, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsSupplierProvider.class)
|
||||
void givenLazyOptionalWhenNotNullThenReturnsDefault(String givenValue, String expected,
|
||||
Supplier<String> expensiveSupplier) {
|
||||
String actual = Optional.ofNullable(givenValue).orElseGet(expensiveSupplier);
|
||||
assertDefaultConversion(givenValue, expected, actual);
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsProvider.class)
|
||||
void givenGuavaWhenNotNullThenReturnsDefault(String givenValue, String defaultValue) {
|
||||
String actual = MoreObjects.firstNonNull(givenValue, defaultValue);
|
||||
assertDefaultConversion(givenValue, defaultValue, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsProvider.class)
|
||||
void givenGuavaOptionalWhenNotNullThenReturnsDefault(String givenValue, String defaultValue) {
|
||||
String actual = com.google.common.base.Optional.fromNullable(givenValue).or(defaultValue);
|
||||
assertDefaultConversion(givenValue, defaultValue, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsProvider.class)
|
||||
void givenApacheWhenNotNullThenReturnsDefault(String givenValue, String defaultValue) {
|
||||
String actual = ObjectUtils.firstNonNull(givenValue, defaultValue);
|
||||
assertDefaultConversion(givenValue, defaultValue, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ObjectsSupplierProvider.class)
|
||||
void givenLazyApacheWhenNotNullThenReturnsDefault(String givenValue, String expected,
|
||||
Supplier<String> expensiveSupplier) {
|
||||
String actual = ObjectUtils.getFirstNonNull(() -> givenValue, expensiveSupplier);
|
||||
assertDefaultConversion(givenValue, expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAllNullsWithObjectsWhenNotNullThenThrowException() {
|
||||
assertThatExceptionOfType(NullPointerException.class)
|
||||
.isThrownBy(() -> requireNonNullElse(null, null));
|
||||
}
|
||||
|
||||
private static void assertDefaultConversion(String given, String expected, String actual) {
|
||||
if (given == null) {
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
} else {
|
||||
assertThat(actual).isEqualTo(given);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class NullReturningPersonChainProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
Person person = new Person();
|
||||
Address address = new Address();
|
||||
ZipCode zipCode = new ZipCode("98-323");
|
||||
address.setZipCode(zipCode);
|
||||
person.setAddress(address);
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(PersonMutatorUtil.cloneAndMutate(person, p -> p.getAddress().getZipCode().setCode(""))),
|
||||
Arguments.of(PersonMutatorUtil.cloneAndMutate(person, p -> p.getAddress().setZipCode(null))),
|
||||
Arguments.of(PersonMutatorUtil.cloneAndMutate(person, p -> p.setAddress(null)))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class ObjectsProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
return Stream.of(
|
||||
Arguments.of(null, "default"),
|
||||
Arguments.of("not null", "default")
|
||||
);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class ObjectsSupplierProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
Supplier<String> supplier = () -> "default";
|
||||
return Stream.of(
|
||||
Arguments.of(null, "default", supplier),
|
||||
Arguments.of("not null", "default", supplier)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
import com.baeldung.nullconversion.service.OnePersonExplicitDeliveryService;
|
||||
import com.baeldung.nullconversion.service.OnePersonGuavaOptionalDeliveryService;
|
||||
import com.baeldung.nullconversion.service.OnePersonOptionalDeliveryService;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
||||
class OnePersonDeliveryServiceUnitTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(PersonProvider.class)
|
||||
void givenMockDeliverServiceWhenNullValuesThenExplicitServiceHandleThem(Person person, Delivery expected) {
|
||||
DeliveryService deliveryService = new OnePersonExplicitDeliveryService(person);
|
||||
Delivery actual = deliveryService.calculateDeliveryForPerson(1L);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(PersonProvider.class)
|
||||
void givenMockDeliverServiceWhenNullValuesThenOptionalServiceHandleThem(Person person, Delivery expected) {
|
||||
DeliveryService deliveryService = new OnePersonOptionalDeliveryService(person);
|
||||
Delivery actual = deliveryService.calculateDeliveryForPerson(1L);
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(NullReturningPersonChainProvider.class)
|
||||
void givenMockDeliverServiceWhenNullValuesThenGuavaOptionalServiceThrowsException(Person person) {
|
||||
DeliveryService deliveryService = new OnePersonGuavaOptionalDeliveryService(person);
|
||||
assertThatExceptionOfType(NullPointerException.class)
|
||||
.isThrownBy(() -> deliveryService.calculateDeliveryForPerson(1L));
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class PersonMutatorUtil {
|
||||
|
||||
public static Person cloneAndMutate(Person person, Consumer<Person> mutator) {
|
||||
Person clone = person.clone();
|
||||
mutator.accept(clone);
|
||||
return clone;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.nullconversion;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
|
||||
public class PersonProvider implements ArgumentsProvider {
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
Person person = new Person();
|
||||
Address address = new Address();
|
||||
ZipCode zipCode = new ZipCode("98-323");
|
||||
address.setZipCode(zipCode);
|
||||
person.setAddress(address);
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(person, Delivery.freeDelivery()),
|
||||
Arguments.of(cloneAndMutate(person, p -> p.getAddress().getZipCode().setCode("")), null),
|
||||
Arguments.of(cloneAndMutate(person, p -> p.getAddress().setZipCode(null)), null),
|
||||
Arguments.of(cloneAndMutate(person, p -> p.setAddress(null)), null),
|
||||
Arguments.of(null, null)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private static Person cloneAndMutate(Person person, Consumer<Person> mutator) {
|
||||
Person clone = person.clone();
|
||||
mutator.accept(clone);
|
||||
return clone;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.nullconversion.service;
|
||||
|
||||
import com.baeldung.nullconversion.Address;
|
||||
import com.baeldung.nullconversion.Delivery;
|
||||
import com.baeldung.nullconversion.DeliveryService;
|
||||
import com.baeldung.nullconversion.Person;
|
||||
import com.baeldung.nullconversion.ZipCode;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class MockOnePersonDeliveryServiceBase implements DeliveryService {
|
||||
|
||||
private final Person person;
|
||||
|
||||
public MockOnePersonDeliveryServiceBase(Person person) {
|
||||
this.person = person;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Delivery calculateDeliveryForPerson(Long id) {
|
||||
Person person = getPersonById(id);
|
||||
if (person != null && person.getAddress() != null && person.getAddress().getZipCode() != null) {
|
||||
ZipCode zipCode = person.getAddress().getZipCode();
|
||||
String code = zipCode.getCode();
|
||||
return calculateDeliveryForZipCode(code);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Delivery calculateDeliveryForPersonWithOptional(Long id) {
|
||||
return Optional.ofNullable(getPersonById(id))
|
||||
.map(Person::getAddress)
|
||||
.map(Address::getZipCode)
|
||||
.map(ZipCode::getCode)
|
||||
.map(this::calculateDeliveryForZipCode)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
protected Person getPersonById(Long id) {
|
||||
return person;
|
||||
}
|
||||
|
||||
protected Delivery calculateDeliveryForZipCode(String zipCode) {
|
||||
if (zipCode == null || zipCode.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return Delivery.freeDelivery();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.nullconversion.service;
|
||||
|
||||
import com.baeldung.nullconversion.Delivery;
|
||||
import com.baeldung.nullconversion.Person;
|
||||
import com.baeldung.nullconversion.ZipCode;
|
||||
|
||||
public class OnePersonExplicitDeliveryService extends MockOnePersonDeliveryServiceBase {
|
||||
|
||||
|
||||
public OnePersonExplicitDeliveryService(Person person) {
|
||||
super(person);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Delivery calculateDeliveryForPerson(Long id) {
|
||||
Person person = getPersonById(id);
|
||||
if (person != null && person.getAddress() != null && person.getAddress().getZipCode() != null) {
|
||||
ZipCode zipCode = person.getAddress().getZipCode();
|
||||
String code = zipCode.getCode();
|
||||
return calculateDeliveryForZipCode(code);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.nullconversion.service;
|
||||
|
||||
import com.baeldung.nullconversion.Address;
|
||||
import com.baeldung.nullconversion.Delivery;
|
||||
import com.baeldung.nullconversion.Person;
|
||||
import com.baeldung.nullconversion.ZipCode;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
public class OnePersonGuavaOptionalDeliveryService extends MockOnePersonDeliveryServiceBase {
|
||||
|
||||
|
||||
public OnePersonGuavaOptionalDeliveryService(Person person) {
|
||||
super(person);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Delivery calculateDeliveryForPerson(Long id) {
|
||||
return Optional.fromNullable(getPersonById(id))
|
||||
.transform(Person::getAddress)
|
||||
.transform(Address::getZipCode)
|
||||
.transform(ZipCode::getCode)
|
||||
.transform(this::calculateDeliveryForZipCode)
|
||||
.orNull();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.nullconversion.service;
|
||||
|
||||
import com.baeldung.nullconversion.Address;
|
||||
import com.baeldung.nullconversion.Delivery;
|
||||
import com.baeldung.nullconversion.Person;
|
||||
import com.baeldung.nullconversion.ZipCode;
|
||||
import java.util.Optional;
|
||||
|
||||
public class OnePersonOptionalDeliveryService extends MockOnePersonDeliveryServiceBase {
|
||||
|
||||
|
||||
public OnePersonOptionalDeliveryService(Person person) {
|
||||
super(person);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Delivery calculateDeliveryForPerson(Long id) {
|
||||
return Optional.ofNullable(getPersonById(id))
|
||||
.map(Person::getAddress)
|
||||
.map(Address::getZipCode)
|
||||
.map(ZipCode::getCode)
|
||||
.map(this::calculateDeliveryForZipCode)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue