Mocking method behaviour based on the field of the parameter Java 8 - java

I have a class definition as follows:
public class MyClass {
public performExecution(ParamsClass paramsClassObject);
}
public ParamsClass {
private String field1;
private String field2;
}
Now, I want to mock the method performExecution based on the field1, but there is no direct way to do it even with the ArgumentMatchers.
Suppose I mocked the class:
MyClass myClass = mock(MyClass.class)
Now, I want to perform something like this:
when the Params object passed in myClass.performExecution() has the field1 value as "1", then give a certain response, otherwise some other response.
Is that a way to do that ?

There are a couple of options:
Option 1: Custom argument matcher
See for example Custom Argument Matcher by baeldung
Option 2: when / thenAnswer
#Test
void testThenAnswer() {
MyClass myCollaborator = Mockito.mock(MyClass.class);
when(myCollaborator.performExecution(any(ParamsClass.class)))
.thenAnswer((invocationOnMock -> {
ParamsClass params = invocationOnMock.getArgument(0);
return "f1".equals(params.getField1())
? "V1"
: "V2";
}));
var result = myCollaborator.performExecution(new ParamsClass("f1", "f2"));
Assertions.assertThat(result).isEqualTo("V1");
}
Option 3: argThat Matcher
#Test
void testArgThat() {
MyClass myCollaborator = Mockito.mock(MyClass.class);
when(myCollaborator.performExecution(Mockito.argThat(p -> p != null && "f1".equals(p.getField1())))).thenReturn("V1");
when(myCollaborator.performExecution(Mockito.argThat(p -> p != null && !"f1".equals(p.getField1())))).thenReturn("V2");
var result = myCollaborator.performExecution(new ParamsClass("f1", "f2"));
Assertions.assertThat(result).isEqualTo("V1");
}
Note null checks in argThat matchers

Related

Resolving value with different behavior, preferably without if else

Here is what I'm trying to do
First initiate an optional variable, then do procedure A.
if procedure A yield null then try procedure B and so on.
if all the procedure still yield null, throw exception
#pseudocode
Optional<> someVariable;
if (someVariable is empty):
fetch value through procedure A
assign to someVariable
if (someVariable is empty):
fetch value through procedure B
assign to someVariable
.
.
.
if still empty:
throw exception
The problem is I don't really want to go through procedure B if procedure A already resolve the value and I don't think it is scalable if more procedure is added
any input?
This has no else
public static void main(String[] args) {
Integer result = null;
if ((result = procA()) == null && (result = procB()) == null){
System.out.println("throw ex");
}
}
static Integer procA () {
System.out.println("procA");
return null;
}
static Integer procB () {
System.out.println("procB");
return null;
}
Try changing the values of what the methods return.
With JDK 11 (probably JDK 8+):
public class MyClass {
private Integer procedureA() {
return ...
}
private Integer procedureB() {
return ...
}
...
private final List<Supplier<Integer>> procedures = List.of(
this::procedureA,
this::procedureB,
// ... as many as you want
);
// This code will stay the same, no matter how many procedures you add
public Optional<Integer> readValue() {
Integer someValue = procedures
.stream()
.map( Supplier::get )
.filter( Objects::nonNull )
.findFirst()
.orElseThrow( () -> new RuntimeException( "Exception!" ) );
// I don't think it makes sense to return an optional in this case
// but you can do it if you want to
return Optional.of(someValue);
}
}
This is pretty much the same approach everybody else has suggested, but with the latest Java you can write code that's much more compact and understandable than the one I've seen in the other answers.
A slightly verbose but hopefully readable approach:
Object someVariable = Stream.of(initialValue)
.map(obj -> obj == null ? procedureA() : obj)
.map(obj -> obj == null ? procedureB() : obj)
.findFirst()
.orElseThrow(NoSuchElementException::new); // or whatever exception you want
If your procedures are relatively simple and can be declared as Runnables. Then we can create a list of Runnables and execute the run method with a for loop:
private class ProcedureA implements Runnable {
#Override
public void run() {
someVariable = try fetching value
}
}
// private class ProcedureB/C/D/E implements Runnable {}
List<Runnable> procedures = List.of(new ProcedureA(), new ProcedureB(), ...);
for (Runnable procedure : procedures) {
if (someVariable.isPresent()) {
break;
}
procedure.run();
}
if (someVariable.isEmpty()) {
throw exception;
}
If the procedures are somewhat complicated, and will return values or take arguments, then we can use Callable or define a custom Procedure interface with a running method.
public interface Procedure {
V running(arg1, arg2);
}
public class ProcedureA implements Procedure {
#Override
public V running(arg1, arg2) {}
}
List<Procedure> procedures = List.of(new ProcedureA() ...);

How does java lambdas external references work?

I'm wondering how does lambdas external references work. Let me explain:
Suppose i have this supplier implementation and this model class :
public class TestSupplierImpl implements Supplier<Boolean> {
public Predicate<Integer> predicate;
public TestSupplierModel model;
public TestSupplierImpl() {
this.predicate = i -> model.something.equals(i);
}
#Override
public Boolean get() {
return predicate.test(3);
}
}
class TestSupplierModel {
public Integer something;
public TestSupplierModel(Integer something) {
this.something = something;
}
}
Then i execute the following code:
TestSupplierImpl test = new TestSupplierImpl(); // line 1
test.model = new TestSupplierModel(3); // line 2
Boolean resultado = test.get(); // line 3
Line 1: creating a new instance of TestSupplierImpl. This new instance's predicate has a null reference of model. This makes sense because at the moment of creation of the predicate, model reference is null.
Line 2: assign to variable model a new instance of TestSupplierModel.
Line 3: test.predicate now has model reference with the new assigned value. Why is this ?
I don't understand why ,when I changed model reference, the predicate updates its model reference to the new one. How is that ?
Thanks in advance !
Does it make sense if you rewrote your TestSupplierImpl() constructor as follows?
public Predicate<Integer> predicate;
public TestSupplierModel model;
public TestSupplierImpl() {
// same effect as this.predicate = i -> model.something.equals(i);
this.predicate = new Predicate<Integer>() {
public boolean test(Integer i) {
return model.something.equals(i);
}
};
}
#Override
public Boolean get() {
return predicate.test(3);
}
So here is the order of things.
// the constructor is run and the test method defined BUT NOT executed.
TestSupplierImpl test = new TestSupplierImpl(); // line 1
// Now you define model
test.model = new TestSupplierModel(3); // line 2
// Then you execute the predictate via get()
Boolean resultado = test.get(); // line 3
model and something aren't required until you issue the get() method. By that time they are already defined.

Graceful alternative to nested Optional.map?

I have multiple Optionals that must be mapped to a POJO. Is there a better alternative than the following?
class SimplePojo {
private String stringField;
private Integer integerField;
// All args. constructor, getter, setter
}
Optional<String> stringOptional = ...
Optional<Integer> integerOptional = ...
Optional<SimplePojo> simplePojoOptional = stringOptional.flatMap(
string -> integerOptional.map(integer -> new SimplePojo(string, integer)))
I have reduced the problem to 2 Optionals in the above example to keep it short. But I actually have 3 Optionals with more on the way. I am afraid the last line can easily become unwieldy soon.
Please note: Use of functional frameworks like Vavr or Functional Java is not an option for me.
How about using a Builder ?
class SimplePojo {
public static class Builder {
private String stringField;
public Builder withStringField(String str) {
this.stringField = str;
return this;
}
// and other "with" methods...
public Optional<SimplePojo> build() {
if (stringField == null || anotherField == null /* and so forth */) {
return Optional.empty();
} else {
return Optional.of(new SimplePojo(this));
}
}
}
private final String stringField;
/* private constructor, so client code has to go through the Builder */
private SimplePojo(Builder builder) {
this.stringField = builder.stringField;
// etc.
}
}
Then you could use it as follows:
SimplePojo.Builder builder = new SimplePojo.builder();
optionalStringField.ifPresent(builder::withStringField);
// etc.
return builder.build();
I do not see any advantage from pursuing the functional style this way here. see three options:
ONE: If you can alter the SimplePojo class and if this scenario is a common one, you might consider to add a factory method to the SimplePojo:
class SimplePojo {
public static Optional<SimplePojo> of(final Optional<String> stringField, final Optional<Integer> integerField) {
if (stringField.isPresent() && integerField.isPresent()) {
return new SimplePojo(stringField.get(), integerField.get());
else
return Optional.empty();
}
}
TWO: If you cannot alter the SimplePojo, you might want to create this as a utility method somewhere else. If you need this pattern only in one class, make the method private in this class!
THREE: If you need to do this only once or twice, I would prefer the if...then construction from the first option over the functional notation you used for the sake of readability:
final Optional<SimplePojo> simplePojoOptional;
if (stringField.isPresent() && integerField.isPresent()) {
simplePojoOptional = new SimplePojo(stringField.get(), integerField.get());
else
simplePojoOptional = Optional.empty();

Validating search parameters using predicates

I have a validate() method that checks the arguments passed in a rest url.
The arguments are linked to a model class like the following
class SearchCriteria {
String regno;
String hostid;
String domid;
String location;
String provider;
/*Getters and Setters*/
}
I have a utility class that checks if the arguments are set or not.
public class SearchCriteriaUtil {
public static boolean isRegnoSet(SearchCriteria criteria) {
return null != criteria.getRegno();
}
public static boolean isHostIdSet(SearchCriteria criteria) {
return null != criteria.getHostId();
}
/* Similarly for domid, location, provider */
}
I have a predicate that tests based on the conditions provided in the util and generates a Truth Value String
public class ParameterPredicate<T> implements Predicate<T>{
final Predicate<T> predicate;
final String sequence;
public ParameterPredicate(Predicate<T> predicate, String sequence) {
this.predicate = predicate;
this.sequence = sequence;
}
#Override
public String toString() {
return sequence;
}
#Override
public boolean test(T t) {
return predicate.test(t);
}
}
Now, based on the arguments set/notset,
regno -set, hostid -set, domid - notset, location - notset, provider - set
My Predicate should evaluate based on the conditions in SearchCriteriaUtil and set the sequence to the appropriate Truth Values...in this case "T T F F T"
In my validate method,
public void validateCriteria(SearchCriteria criteria) {
List<Predicate<SearchCriteria>> SearchCriteriaPredicate = Arrays.asList(SearchCriteriaUtil::isRegnoSet, SearchCriteriaUtil::isHostIdSet,
SearchCriteriaUtil::isDomidSet,
SearchCriteriaUtil::isLocationSet,
SearchCriteriaUtil::isProviderSet,
Collection<String> desired = Arrays.asList("T F F F F", "T F T T F", "T F T T F", "T F F F T", "T F F F T", "F T F F F");
I am not able to proceed beyond this point, I have to set the sequence and check if it exists in the desired list of truth values.
I was refering to a previous post : Filtering with truth tables
As I am new to java 8, any help is appreciated.
Instead of using a util class and dealing with Strings in order to check if a combination of criteria is valid, why not just add something like the following inside your SearchCriteria class:
public boolean hasDesiredCombination() {
return Criterion.DESIRED_COMBINATONS.contains(
Arrays.stream(Criterion.values())
.filter(s -> s.predicate.test(this))
.collect(Collectors.toCollection(
() -> EnumSet.noneOf(Criterion.class)))
);
}
private static enum Criterion {
REGNO(s -> s.regno != null),
HOSTID(s -> s.hostid != null),
DOMID(s -> s.domid != null),
LOCATION(s -> s.location != null),
PROVIDER(s -> s.provider != null);
private static Set<Set<Criterion>> DESIRED_COMBINATONS =
new HashSet<>(Arrays.asList(
EnumSet.of(REGNO),
EnumSet.of(REGNO, DOMID, LOCATION),
EnumSet.of(REGNO, PROVIDER),
EnumSet.of(HOSTID)
));
private Predicate<SearchCriteria> predicate;
private Criterion(Predicate<SearchCriteria> predicate) {
this.predicate = predicate;
}
}
Advantages:
You don't necessarily have to expose getters and setters
It's immediately clear from the source code which combinations are desired
The logic is where it belongs: (indirectly) inside the SearchCriteria class
I'm not sure what the purpose of ParameterPredicate is, but if I've understood correctly, you want check whether a combination of validations (SearchCriteriaPredicate) matches one of a predefined set (desired). If so, this should do it:
String sequence = SearchCriteriaPredicate.stream()
.map(p -> p.test(criteria) ? "T" : "F")
.collect(Collectors.joining(" "));
return desired.contains(sequence);

Optionally getting field

I have a class structure like this:
public class Foo {
private FooB foob;
public Optional<FooB> getFoob() {
return Optional.ofNullable(foob);
}
}
public class FooB {
private int valA;
public int getValA() {
return valA;
}
}
My objective is to call the get method for fooB and then check to see if it's present. If it is present then return the valA property, if it doesn't then just return null. So something like this:
Integer valA = foo.getFoob().ifPresent(getValA()).orElse(null);
Of course this isn't proper Java 8 optional syntax but that's my "psuedo code". Is there any way to achieve this in Java 8 with 1 line?
What you are describing is the method Optional.map:
Integer valA = foo.getFoob().map(foo -> foo.getValA()).orElse(null);
map lets you transform the value inside an Optional with a function if the value is present, and returns an empty the optional if the value in not present.
Note also that you can return null from the mapping function, in which case the result will be Optional.empty().
Why you dont add a getValue methode to the class Foo? This would be a kind of delegation.
public class Foo {
...
public Integer getValue() {
if (foob == null) {
return null;
}
return foob.getValA();
}
}

Categories

Resources