creating a custom argument matcher confusing implementation - java

I have seen someone creating a custom argument matcher like the following. However, I am having difficulty understanding how it works.
What I can understand its a method that takes a parameter and returns a ArgumentMatcher which is an interface that has a type of List<Person>. And the overriden method is the matcher that uses a lambda. I think the body part is the most confusing, if anyone can explain that.
private ArgumentMatcher<List<Person> personListSize(final int size) {
return argument -> argument.personList().size() == size;
}
This is the way I would normally do something like this, which to me is easier to understand, just wondering how can I get the following to look like the above?
public class CustomArgumentMatcher implements ArgumentMatcher<List<Person>> {
#Override
public boolean matches(List<Person> argument) {
return argument.size() == size;
}
}
Just starting to understand, this works:
private ArgumentMatcher<String> stringMatcher = new ArgumentMatcher<String>() {
#Override
public boolean matches(String argument) {
return argument.contains("");
}
};
However, If I add a parameter to pass in like this:
private ArgumentMatcher<String> stringMatcherArgs(final String name) = new ArgumentMatcher<String>() {
}
I get a error message saying unexpected token just wondering to pass in a parameter in the above?

You should read this document about Lambda Expressions
Here are your examples:
private ArgumentMatcher<List<Person>> customArgumentMatcher(final int size) {
return argument -> argument.size() == size;
}
private ArgumentMatcher<List<Person>> stringMatcherArgs(final String name) {
return argument -> argument.contains(name);
}

You got it all correct just connect the dots...
private ArgumentMatcher<List<Person> personListSize(final int size) {
return new ArgumentMatcher<List<Person>>() {
#Override
public boolean matches(List<Person> argument) {
return argument.size() == size;
}
};
}
and use it with argThat
Mockito.verify(mockClass).foo(argThat(personListSize(5));

If your still looking for the kotlin equivalent of Gustavo`s answer
(note that you should have created another question instead),
try the following:
fun customArgumentMatcher(size : Int) : ArgumentMatcher<List<Person>> {
return object : ArgumentMatcher<List<Person>> {
override fun matches(argument : List<Person>) = argument.size == size;
}
}
See also:
Setting anonymous interface in Kotlin

Related

Java imitate and, or for concatenate rule

I have a Java class like below
class MyClass {
public boolean rule1() {...}
public boolean rule2() {...}
public boolean rule3() {...}
}
now for instance I want to check the rule of above class in many ways such as :
MyClass myClass = new MyClass();
if (myClass.rule1() && myClass.rule2 || myClass.rule3) {}
and Now I am wondering that how can I implement above line with like this one?
if (myClass.rule1().and().rule2().or().rule3().accept()) {}
The cleaner way would be to use the functional interface Predicate:
Type Parameters:
T - the type of the input to the predicate Functional
Interface: This is a functional interface and can therefore be used as
the assignment target for a lambda expression or method reference.
public class A {
public Predicate rule1() {
return //some operation that returns a boolean;
}
public Predicate rule2() {
return //some operation that returns a boolean;
}
public Predicate rule3() {
return //some operation that returns a boolean;
}
}
But the if chain of method calls would not look like you are looking for, namely:
if (myClass.rule1().and().rule2().or().rule3().accept()) {}
Otherwise, you would have to implement the Builder pattern, and implement the and(), or(), and accept methods. For instance:
public class BooleanEvaluator {
List<String> rules = new ArrayList<>();
public BooleanEvaluator and() {
rules.add("&&");
return this;
}
public BooleanEvaluator or() {
rules.add("or");
return this;
}
public boolean accept() {
int i = 0;
boolean result = Boolean.parseBoolean(rules.get(0));
while (i < rules.size() - 1) {
if(rules.get(i).equals("&&")){
result = result && Boolean.parseBoolean(rules.get(i + 1));
i+=2;
}
else if(rules.get(i).equals("||")){
result = result || Boolean.parseBoolean(rules.get(i + 1));
i+=2;
}
}
return false;
}
public BooleanEvaluator rule1() {
boolean result = // apply the rule 1
rules.add(String.valueOf(result));
return this;
}
public BooleanEvaluator rule2() {
boolean result = // apply the rule 2
rules.add(String.valueOf(result));
return this;
}
public BooleanEvaluator rule3() {
boolean result = // apply the rule 3
rules.add(String.valueOf(result));
return this;
}
void some_method(){
if (this.rule1().and().rule2().or().rule3().accept()) {
// ...
}
}
}
Naturally, the accept method would have to be much more robust, this is just to show what would the design look like.
Have a look at Predicate<T> and its and or or.
MyClass instance = new MyClass();
Predicate<MyClass> predicate = MyClass::rule1;
if (predicate.and(MyClass::rule2).or(MyClass::rule3).test(instance)) {
// todo
}
It might look less readable than the version you mentioned, renaming MyClass to something more meaningful would help. If it doesn't work for you, consider writing a Builder. Good complex examples of which can be found in, let's say, dynamic SQL builders (for example, jooq).

How can I achieve Null-safety when calling a method written in Java from Kotlin, which throws an exception?

I am trying to rewrite a class with Kotlin in a Java product.
Our Java product has custom exceptions written like this:
public class AppError {
public static void exit(int res_code) {
throw new AppException(res_code);
}
...
}
public class AppException extends RuntimeException {
private int res_code = CommonResCode.ERROR;
public AppException() { super(); }
public AppException(int res_code) {
super();
this.res_code = res_code;
}
}
So in the existing code, there are codes like:
int point = null;
point = someMap.get("foo")
if (point == null) {
AppError.exit(THE_GIVEN_PARAMETER_IS_INVALID_CODE)
}
I want to rewrite this code with something like the Kotlin's
val point: Int = someMap.getOrElse("foo", { AppError.exit(...) })
// or
val point: Int = someMap["foo"] ?: AppError.exit(...)
But since the exit method is seen as returning Unit, Kotlin says that point is both Int and Unit and suggests me to define point as Any.
What can I do to avoid this? (other than doing the same as the Java code?)
Edit
Since the code logically always throws an exception, I thought casting may be the simple way:
val point: Int = someMap.getOrElse("foo", { AppError.exit(...) }) as Int
Is this correct? Or should I avoid doing this?
Well, the method is returning void (the Unit in Kotlin). Or rather, the method is never returning "normally" at all. It never finishes, because it always throws an exception.
AFAIK, there's nothing built-in which allows the use of custom exceptions. You could however create a new helper method similar to Java's Objects.requireNonNull or Kotlin's !! (sure operator):
static <T> T requireOrThrow(final T value, final Supplier<Throwable> exceptionSupplier) {
// be aware of boxing of primitive types
if (value == null) throw exceptionSupplier.get();
return value;
}
This can then be used from your Java …
int point = requireOrThrow(someMap.get("foo"), () -> new AppException(THE_GIVEN_PARAMETER_IS_INVALID_CODE));
… and Kotlin code, which should simplify both
val point: Int = requireOrThrow(someMap["foo"], { AppException(THE_GIVEN_PARAMETER_IS_INVALID_CODE) });
In Kotlin you can write val point: Int = someMap["foo"] ?: error(ERROR_MESSAGE) because error function returns Nothing.
So to make val point: Int = someMap["foo"] ?: AppError.exit(...) compile, you should make AppError.exit(...) return Nothing.
Unfortunately, only Kotlin functions can return Nothing, but there are still a few solutions to your problem:
1. Make AppError.exit(...) return JNothing:
public class AppError {
public static JNothing exit(int res_code) {
throw new AppException(res_code);
}
}
Where JNothing is:
public final class JNothing {
private JNothing() {}
}
JNothing to Nothing converter:
operator fun JNothing.invoke(): Nothing {
error("Illegal JNothing instance was created [$this]")
}
Use case:
val point: Int = someMap["foo"] ?: AppError.exit(code)()
2. Create KAppError.exit() wrapper of AppError.exit() which returns Nothing:
object KAppError {
fun exit(res_code: Int): Nothing = mustThrow {
AppError.exit(res_code)
}
}
Where mustThrow is:
#PublishedApi
internal const val EXCEPTION_HAS_NOT_BEEN_THROWN = "Exception was expected, but it hasn't been thrown!"
inline fun mustThrow(block: () -> Unit): Nothing {
block()
error(EXCEPTION_HAS_NOT_BEEN_THROWN)
}
Use cases:
val point: Int = someMap["foo"] ?: KAppError.exit(code)
val point1: Int = someMap["foo"] ?: mustThrow { AppError.exit(code) }
3. Make AppError.exit() return whatever is required:
public class AppError {
public static <Nothing> Nothing exit(int res_code) {
throw new AppException(res_code);
}
}
Use case:
val point: Int = someMap["foo"] ?: AppError.exit(code)
4. Make AppError.exit() return exception instead of throwing it:
public class AppError {
public static AppException exit(int res_code) {
return new AppException(res_code);
}
}
Use case:
val point: Int = someMap["foo"] ?: throw AppError.exit(code)
You can write a helper method in Kotlin which returns Nothing to indicate it never returns:
object AppErrorK {
fun exit(res_code: Int): Nothing {
AppError.exit(res_code)
// will never actually be reached, but makes Kotlin accept the correct return type
throw Exception()
}
}
Then things like
someMap["foo"] ?: AppErrorK.exit(...)
will work.

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();
}
}

Mockito return value based on property of a parameter

Normally when using Mockito I will do something like:
Mockito.when(myObject.myFunction(myParameter)).thenReturn(myResult);
Is it possible to do something along the lines of
myParameter.setProperty("value");
Mockito.when(myObject.myFunction(myParameter)).thenReturn("myResult");
myParameter.setProperty("otherValue");
Mockito.when(myObject.myFunction(myParameter)).thenReturn("otherResult");
So rather than when just using the parameter to determine the result. It is using a value of a property inside the parameter to determine the result.
So when the code is executed it behaves like so:
public void myTestMethod(MyParameter myParameter,MyObject myObject){
myParameter.setProperty("value");
System.out.println(myObject.myFunction(myParameter));// outputs myResult
myParameter.setProperty("otherValue");
System.out.println(myObject.myFunction(myParameter));// outputs otherResult
}
Here is the current solution, hopefully something better can be suggested.
private class MyObjectMatcher extends ArgumentMatcher<MyObject> {
private final String compareValue;
public ApplicationContextMatcher(String compareValue) {
this.compareValue= compareValue;
}
#Override
public boolean matches(Object argument) {
MyObject item= (MyObject) argument;
if(compareValue!= null){
if (item != null) {
return compareValue.equals(item.getMyParameter());
}
}else {
return item == null || item.getMyParameter() == null;
}
return false;
}
}
public void initMock(MyObject myObject){
MyObjectMatcher valueMatcher = new MyObjectMatcher("value");
MyObjectMatcher otherValueMatcher = new MyObjectMatcher("otherValue");
Mockito.when(myObject.myFunction(Matchers.argThat(valueMatcher))).thenReturn("myResult");
Mockito.when(myObject.myFunction(Matchers.argThat(otherValueMatcher))).thenReturn("otherResult");
}
In Java 8 it is even simpler than all of the above:
when(mockObject.myMethod(anyString()))
.thenAnswer(invocation ->
invocation.getArgumentAt(0, String.class));
Here's one way of doing it. This uses an Answer object to check the value of the property.
#RunWith(MockitoJUnitRunner.class)
public class MyTestClass {
private String theProperty;
#Mock private MyClass mockObject;
#Before
public void setUp() {
when(mockObject.myMethod(anyString())).thenAnswer(
new Answer<String>(){
#Override
public String answer(InvocationOnMock invocation){
if ("value".equals(theProperty)){
return "result";
}
else if("otherValue".equals(theProperty)) {
return "otherResult";
}
return theProperty;
}});
}
}
There's an alternative syntax, which I actually prefer, which will achieve exactly the same thing. Over to you which one of these you choose. This is just the setUp method - the rest of the test class should be the same as above.
#Before
public void setUp() {
doAnswer(new Answer<String>(){
#Override
public String answer(InvocationOnMock invocation){
if ("value".equals(theProperty)){
return "result";
}
else if("otherValue".equals(theProperty)) {
return "otherResult";
}
return theProperty;
}}).when(mockObject).myMethod(anyString());
}
Yes you can, using a custom argument matcher.
See the javadoc of Matchers for more details, and more specifically ArgumentMatcher.
Here is how it would look like in Kotlin with mockito-kotlin library.
mock<Resources> {
on {
mockObject.myMethod(any())
} doAnswer {
"Here is the value: ${it.arguments[0]}"
}
}
You can do this with Mockito 3.6.0:
when(mockObject.myMethod(anyString()))
.thenAnswer(invocation -> myStringMethod(invocation.getArgument(0)));
This answer is based on Sven's answer and Martijn Hiemstra's comment, with getArgumentAt() changed to getArgument().

Dynamic Return Type in Java method

I've seen a question similar to this multiple times here, but there is one big difference.
In the other questions, the return type is to be determined by the parameter. What I want/need to do is determine the return type by the parsed value of a byte[]. From what I've gathered, the following could work:
public Comparable getParam(String param, byte[] data) {
if(param.equals("some boolean variable")
return data[0] != 0;
else(param.equals("some float variable") {
//create a new float, f, from some 4 bytes in data
return f;
}
return null;
}
I just want to make sure that this has a chance of working before I screw anything up. Thanks in advance.
I don't know what these people are talking about. You lose type safety, which is a concern, but you could easily accomplish this with generics...something like:
public <T> T getSomething(...) { }
or
interface Wrapper<T> { T getObject(); }
public <T> Wrapper<T> getSomething(...) { }
The latter promotes the possibility of a strategy pattern. Pass the bytes to the strategy, let it execute and retrieve the output. You would have a Byte strategy, Boolean strategy, etc.
abstract class Strategy<T> {
final byte[] bytes;
Strategy(byte[] bytes) { this.bytes = bytes; }
protected abstract T execute();
}
then
class BooleanStrategy extends Strategy<Boolean> {
public BooleanStrategy(byte[] bytes) { super(bytes); }
#Override
public Boolean execute() {
return bytes[0] != 0;
}
}
Your example code is a bad use case though and I wouldn't recommend it. Your method doesn't make much sense.
This CAN be done. The following code will work:
public byte BOOLEAN = 1;
public byte FLOAT = 2;
public static <Any> Any getParam(byte[] data) {
if (data[0] == BOOLEAN) {
return (Any)((Boolean)(boolean)(data[1] != 0));
} else if (data[0] == FLOAT) {
return (Any)((Float)(float)data[1]);
} else {
return null;
}
}
By using a generic for the return type any Java method can dynamically return any object or primitive types. You can name the generic whatever you want, and in this case I called it 'Any'. Using this code you avoid casting the return type when the method is called. You would use the method like so:
byte[] data = new byte[] { 1, 5 };
boolean b = getParam(data);
data = new byte[] { 2, 5 };
float f = getParam(data);
The best you can do without this trick is manually casting an Object:
float f = (float)getParam(data);
Java dynamic return types can reduce boilerplate code.
You can't do it. Java return types have to be either a fixed fundamental type
or an object class. I'm pretty sure the best you can do is return a wrapper type
which has methods to fetch various possible types of values, and an internal enum
which says which one is valid.
--- edit --- after Danieth's correction!
public <Any> Any getParam(boolean b){
return((Any)((Boolean)(!b)));
}
public <Any> Any getParam(float a) {
return((Any)((Float)(a+1)));
}
public <Any> Any getParam(Object b) {
return((Any)b);
}
public void test(){
boolean foo = getParam(true);
float bar = getParam(1.0f);
float mumble = getParam(this); // will get a class cast exception
}
You still incur some penalties for boxing items and type checking
the returned values, and of course if your call isn't consistent with
what the implementations of getParam actually do, you'll get a class
cast exception.
My 2 cents with an example with Google HTTP client:
static public <Any> Any getJson(final String url, final Class<Any> parseAs) throws IOException {
HttpRequestFactory requestFactory
= HTTP_TRANSPORT.createRequestFactory(
(HttpRequest request) -> {
request.setParser(new JsonObjectParser(JSON_FACTORY));
});
HttpRequest request = requestFactory.buildRequest(HttpMethods.GET, new GenericUrl(url), null);
return request.execute().parseAs(parseAs);
}
Can be use like this:
HashMap<String, Object> out = HttpUtils.getJson( "https://api.qwant.com", HashMap.class);
If you are really only returning a boolean or a float, then the best you can do is Object.
If you are returning variable objects, you have to choose a return type with the least common superclass. Primitives don't have a superclass, but they will be boxed into Object representations (like Boolean and Float) which have a common superclass of Object.
It can also be done as the below example:
public class Test
{
public <T> T dynamicReturnMethod(Class<T> clazz)
{
//your code
return class.getDeclaredConstructor().newInstance();
}
//usage
public static void main(String[] args)
{
Test t = new Test();
ClassObjectWhichNeedsToBeReturned obj =
t.dynamicReturnMethod(ClassObjectWhichNeedsToBeReturned.class)
}
}
This has been tested using java 11

Categories

Resources