Checking values extracted from Collection against primitive value in AssertJ - java

I had this case where I needed that all the objects in a collection have a specific boolean value in a field. extracting() seemed like a very good candidate for this. I was able to 'access' the field pretty easily but when I wanted to check it againt the value I was not able to find a clean way to do it in the API. The first thing I came up was the following:
SomeService someService = new SomeService();
List<ClassA> llList = someService.getList();
assertThat(llList).extracting("someBoolean")
.are(new Condition<Object>() {
#Override
public boolean matches(Object o) {
return Boolean.FALSE.equals(o);
}
});
This seems like it is such common thing to check that I am buffled that I could not find something better in the AssertJ API. To enhance readability I next did the the following:
assertThat(llList).extracting("someBoolean")
.are(createBooleanCondition(false));
public static Condition<Object> createBooleanCondition(boolean expected){
return new Condition<Object>() {
#Override
public boolean matches(Object o) {
return new Boolean(expected).equals(o);
}
};
}
Is there a cleaner way to express this kind of assertion with the AssertJ?
NOTE: I could use a java8 lambda to make this cleaner but my question is geared towards assertj and I also have the hard rule that I need this to compile in java 1.7.

To check that every extracted boolean values are false, I would simply do:
assertThat(llList).extracting("someBoolean").containsOnly(Boolean.FALSE);

A quite simple way for that is...
assertThat( llList ).filteredOn( "someBoolean", Boolean.FALSE ).isEmpty();
Of course, this will require reflection on AssertJ's side, but that's the price to pay for something like that...

Related

Checking for duplicated data in Java array list [duplicate]

I want to check whether a List contains an object that has a field with a certain value. Now, I could use a loop to go through and check, but I was curious if there was anything more code efficient.
Something like;
if(list.contains(new Object().setName("John"))){
//Do some stuff
}
I know the above code doesn't do anything, it's just to demonstrate roughly what I am trying to achieve.
Also, just to clarify, the reason I don't want to use a simple loop is because this code will currently go inside a loop that is inside a loop which is inside a loop. For readability I don't want to keep adding loops to these loops. So I wondered if there were any simple(ish) alternatives.
Streams
If you are using Java 8, perhaps you could try something like this:
public boolean containsName(final List<MyObject> list, final String name){
return list.stream().filter(o -> o.getName().equals(name)).findFirst().isPresent();
}
Or alternatively, you could try something like this:
public boolean containsName(final List<MyObject> list, final String name){
return list.stream().map(MyObject::getName).filter(name::equals).findFirst().isPresent();
}
This method will return true if the List<MyObject> contains a MyObject with the name name. If you want to perform an operation on each of the MyObjects that getName().equals(name), then you could try something like this:
public void perform(final List<MyObject> list, final String name){
list.stream().filter(o -> o.getName().equals(name)).forEach(
o -> {
//...
}
);
}
Where o represents a MyObject instance.
Alternatively, as the comments suggest (Thanks MK10), you could use the Stream#anyMatch method:
public boolean containsName(final List<MyObject> list, final String name){
return list.stream().anyMatch(o -> name.equals(o.getName()));
}
You have two choices.
1. The first choice, which is preferable, is to override the `equals()` method in your Object class.
Let's say, for example, you have this Object class:
public class MyObject {
private String name;
private String location;
//getters and setters
}
Now let's say you only care about the MyObject's name, that it should be unique so if two `MyObject`s have the same name they should be considered equal. In that case, you would want to override the `equals()` method (and also the `hashcode()` method) so that it compares the names to determine equality.
Once you've done this, you can check to see if a Collection contains a MyObject with the name "foo" by like so:
MyObject object = new MyObject();
object.setName("foo");
collection.contains(object);
However, this might not be an option for you if:
You are using both the name and location to check for equality, but you only want to check if a Collection has any `MyObject`s with a certain location. In this case, you've already overridden `equals()`.
`MyObject` is part of an API that you don't have liberty to change.
If either of these are the case, you'll want option 2:
2. Write your own utility method:
public static boolean containsLocation(Collection<MyObject> c, String location) {
for(MyObject o : c) {
if(o != null && o.getLocation.equals(location)) {
return true;
}
}
return false;
}
Alternatively, you could extend ArrayList (or some other collection) and then add your own method to it:
public boolean containsLocation(String location) {
for(MyObject o : this) {
if(o != null && o.getLocation.equals(location)) {
return true;
}
}
return false;
}
Unfortunately there's not a better way around it.
This is how to do it using Java 8+ :
boolean isJohnAlive = list.stream().anyMatch(o -> "John".equals(o.getName());
Google Guava
If you're using Guava, you can take a functional approach and do the following
FluentIterable.from(list).find(new Predicate<MyObject>() {
public boolean apply(MyObject input) {
return "John".equals(input.getName());
}
}).Any();
which looks a little verbose. However the predicate is an object and you can provide different variants for different searches. Note how the library itself separates the iteration of the collection and the function you wish to apply. You don't have to override equals() for a particular behaviour.
As noted below, the java.util.Stream framework built into Java 8 and later provides something similar.
Collection.contains() is implemented by calling equals() on each object until one returns true.
So one way to implement this is to override equals() but of course, you can only have one equals.
Frameworks like Guava therefore use predicates for this. With Iterables.find(list, predicate), you can search for arbitrary fields by putting the test into the predicate.
Other languages built on top of the VM have this built in. In Groovy, for example, you simply write:
def result = list.find{ it.name == 'John' }
Java 8 made all our lives easier, too:
List<Foo> result = list.stream()
.filter(it -> "John".equals(it.getName())
.collect(Collectors.toList());
If you care about things like this, I suggest the book "Beyond Java". It contains many examples for the numerous shortcomings of Java and how other languages do better.
Binary Search
You can use Collections.binarySearch to search an element in your list (assuming the list is sorted):
Collections.binarySearch(list, new YourObject("a1", "b",
"c"), new Comparator<YourObject>() {
#Override
public int compare(YourObject o1, YourObject o2) {
return o1.getName().compareTo(o2.getName());
}
});
which will return a negative number if the object is not present in the collection or else it will return the index of the object. With this you can search for objects with different searching strategies.
Map
You could create a Hashmap<String, Object> using one of the values as a key, and then seeing if yourHashMap.keySet().contains(yourValue) returns true.
Eclipse Collections
If you're using Eclipse Collections, you can use the anySatisfy() method. Either adapt your List in a ListAdapter or change your List into a ListIterable if possible.
ListIterable<MyObject> list = ...;
boolean result =
list.anySatisfy(myObject -> myObject.getName().equals("John"));
If you'll do operations like this frequently, it's better to extract a method which answers whether the type has the attribute.
public class MyObject
{
private final String name;
public MyObject(String name)
{
this.name = name;
}
public boolean named(String name)
{
return Objects.equals(this.name, name);
}
}
You can use the alternate form anySatisfyWith() together with a method reference.
boolean result = list.anySatisfyWith(MyObject::named, "John");
If you cannot change your List into a ListIterable, here's how you'd use ListAdapter.
boolean result =
ListAdapter.adapt(list).anySatisfyWith(MyObject::named, "John");
Note: I am a committer for Eclipse ollections.
Predicate
If you dont use Java 8, or library which gives you more functionality for dealing with collections, you could implement something which can be more reusable than your solution.
interface Predicate<T>{
boolean contains(T item);
}
static class CollectionUtil{
public static <T> T find(final Collection<T> collection,final Predicate<T> predicate){
for (T item : collection){
if (predicate.contains(item)){
return item;
}
}
return null;
}
// and many more methods to deal with collection
}
i'm using something like that, i have predicate interface, and i'm passing it implementation to my util class.
What is advantage of doing this in my way? you have one method which deals with searching in any type collection. and you dont have to create separate methods if you want to search by different field. alll what you need to do is provide different predicate which can be destroyed as soon as it no longer usefull/
if you want to use it, all what you need to do is call method and define tyour predicate
CollectionUtil.find(list, new Predicate<MyObject>{
public boolean contains(T item){
return "John".equals(item.getName());
}
});
Here is a solution using Guava
private boolean checkUserListContainName(List<User> userList, final String targetName){
return FluentIterable.from(userList).anyMatch(new Predicate<User>() {
#Override
public boolean apply(#Nullable User input) {
return input.getName().equals(targetName);
}
});
}
contains method uses equals internally. So you need to override the equals method for your class as per your need.
Btw this does not look syntatically correct:
new Object().setName("John")
If you need to perform this List.contains(Object with field value equal to x) repeatedly, a simple and efficient workaround would be:
List<field obj type> fieldOfInterestValues = new ArrayList<field obj type>;
for(Object obj : List) {
fieldOfInterestValues.add(obj.getFieldOfInterest());
}
Then the List.contains(Object with field value equal to x) would be have the same result as fieldOfInterestValues.contains(x);
Despite JAVA 8 SDK there is a lot of collection tools libraries can help you to work with, for instance:
http://commons.apache.org/proper/commons-collections/
Predicate condition = new Predicate() {
boolean evaluate(Object obj) {
return ((Sample)obj).myField.equals("myVal");
}
};
List result = CollectionUtils.select( list, condition );

How can I unit test a method with multiple internal calls to class I want to mock using EasyMock

I would like to unit test a method with multiple internal calls to a class I want to mock using EasyMock.
The test method actually runs 5 times and calls the mocked method.
During each loop, I will create some objects, all of the same class (let's say of class A).
The private method will call the mock object method that takes the instance of class A, evaluate it and return a result.
In the end, the public method will return a List of results.
I tried the standard EasyMock.expect(MockClass.method(A)).andReturn() but it does not work since there is no implementation of equals() for class A:
// this is the method example I am trying to test
public methodToTest(){
// some logic
privateMethodToTest(x);
// some logic
}
private List<B> privateMethodToTest(int x){
List<B> list = new ArrayList<>();
List<A> all = getObjects(x); //getObjects private method
for (A a:all){
list.add(objectToMock.methodToMock(a));
return list;
}
This is how I would like it to work:
EasyMock.createMock(ObjectToMock.class);
EasyMock.expect(ObjectToMock.methodToMock(A)/* when A.getValue() == 1 */.andReturn("B object number 1")
EasyMock.expect(ObjectToMock.methodToMock(A)/* when A.getValue() == 2 */.andReturn("B object number 2")
//... and so on
//object of class A does not implement equals()
I am not sure how to do it and I was not able to find any similar example or answer to my question.
You need another matcher. By default, EasyMock will indeed match using equals. But you can't do that. Your basic choices are:
You don't care about matching precisely
If seems to be the easiest for you. It means doing:
expect(objectToMock.methodToMock(anyObject()).andReturn("B object number 1");
expect(objectToMock.methodToMock(anyObject()).andReturn("B object number 2");
Use a comparator
According to your comment, you might actually prefer this
expect(mock.methodToTest(EasyMock.cmp(new A(1), Comparator.comparingInt(A::getValue), LogicalOperator.EQUAL))).andReturn(1);
The only problem is that you need a A with the correct value to compare with.
To have a simplified version, you can use your own matcher
The expectation using the custom matcher right below.
expect(mock.methodToTest(cmp(0))).andReturn(3);
public static <T> T cmp(int value) {
reportMatcher(new IArgumentMatcher() {
#Override
public boolean matches(Object argument) {
return value == ((A) argument).getValue();
}
#Override
public void appendTo(StringBuffer buffer) {
buffer.append("A.value=").append(value);
}
});
return null;
}
When unittesting we verify public observable behavior of the code under test, that is return values and communication with dependencies.
Anything else is implementation detail which we do not test. The reason is that you might want to refactor your code. That means you want to improve the structure of your code without changing its behavior. Your unittest schould verify that you did not change behavior accidentally. But they can only do this if you do not have to change them too.

Java type specific behaviour with generics

The problem is as follows:
There are the entities Box, Boxvalue, Boxstrategy and then as example "IntegerBoxStrategy".
The concept is quite simple, I'd like to put different kind of types in this box. Sometimes there will be an Integer inside this Box, sometimes a String. I want to be able to do specific conversion between these types (so type specific behaviour -> hence my strategy approach. Every type will require a specific strategy to convert) and these types can be specified with an ENUM.
So after googling a lot (though I'm quite sure this question might be marked as duplicate and say that I haven't googled enough ;) ) i'm trying this approach:
https://www.javaspecialists.eu/archive/Issue123.html
Concise summary of this approach: they use a strategy to implement a taxstrategy for taxpayers. UML will be more easy to understand:
Though in my case, I'd only have one "Taxpayer", aka the BoxType.
fyi: this question is really similar : Conditional behaviour based on concrete type for generic class though -> i want to be able to switch between my BoxValues, and convert "true" into "1". But I think that the approach of the answer might be helpful, Run time type identification. Which in my case would be used to match strategies with their according "supported types".
The problem with the first link is that in every specific strategy implementation, I'm going to have a huge switch. (sample code later on)
My question is not something like "solve this for me please" but more like point me in the general direction. If a simple example could be given how this could be done when you don't have to update every specific strategy implementation when you support a new "boxvaluetype", I'd be really happy. If posssible, I'd like the cleanest design implementation or approach according to the GRASP principles.
public interface typeStrategy {
boolean canChangeToType(Object myvalue,ValueType type);
boolean correctType(Object myvalue);
}
class BoolTypeStrategy implements typeStrategy{
#Override
public boolean canChangeToType(Object myvalue, ValueType type) {
if (correctType(myvalue))
throw new IllegalArgumentException("your initial value should be a boolean!");
switch (type){
case INT:
return true;
case STRING:
return true;
default:
return false;
}
}
#Override
public boolean correctType(Object myvalue) {
if (!(myvalue instanceof Boolean))
return false;
return true;
}
}
In the example, this ValueType is my Enum.
public class BoxValue<T> {
private T value;
private typeStrategy mystrategy;
public BoxValue(T value, typeStrategy strategy) {
this.value = value;
this.mystrategy = strategy;
}
public T getValue() {
return value;
}
public boolean canChangeToType(ValueType type){
return mystrategy.canChangeToType(value, type);
}
}
As you can see, huge switches solve the problem.. So what design patterns, what suggestions are recommended to solve this problem? (fyi: I'd like to resolve this in Java 8, as i am aware that there are these strange "var" types in Java10+)

Why doesn't Google Guava Preconditions's checkArgument return a value?

I really love how guava library allows simple one-liners for checking for null:
public void methodWithNullCheck(String couldBeNull) {
String definitelyNotNull = checkNotNull(couldBeNull);
//...
}
sadly, for simple argument check you need at least two lines of code:
public void methodWithArgCheck(String couldBeEmpty) {
checkArgument(!couldBeEmpty.isEmpty());
String definitelyNotEmpty = couldBeEmpty;
//...
}
however it is possible to add method which could do argument check and return a value if check successful. Below is an example of check and how it could be implemented:
public void methodWithEnhancedArgCheck(String couldBeEmpty) {
String definitelyNotEmpty = EnhancedPreconditions.checkArgument(couldBeEmpty, !couldBeEmpty.isEmpty());
//...
}
static class EnhancedPreconditions {
public static <T> T checkArgument(T reference, boolean expression) {
if (!expression) {
throw new IllegalArgumentException();
}
return reference;
}
}
I just was wondering is that by design and if it is worth to put feature request for that.
EDIT: #Nizet, yeah, checks in methods could be clumsy. However checks in constructors for nulls looks really good and saves a lot of time spent on debugging NPEs:
public class SomeClassWithDependency {
private final SomeDependency someDependency;
public SomeClassWithDependency(SomeDependency someDependency) {
this.someDependency = checkNotNull(someDependency);
}
//...
EDIT: Accepting Nizet's answer because I agree with him on side-effects and consistency reasoning.
Also if you take a look into Xaerxess comment it looks like that causing confusion amongst other developers as well.
The biggest single reason that checkNotNull returns its argument is so it can be used in constructors, like so:
public Foo(Bar bar) {
this.bar = checkNotNull(bar);
}
But the main reason that checkArgument doesn't do something similar is that you'd have to pass the argument separately anyway, and it just doesn't seem worth it -- especially with more complicated precondition checks, which can sometimes be more readable on their own line. Just because something can be a one-liner doesn't mean that it should be, if it doesn't increase readability.
What I've never understood is why checkNotNull() returns its argument in the first place:
public void foo(String bar) {
Preconditions.checkNotNull(bar);
// here, you're sure that bar is not null.
// No need to use another variable or to reassign bar to the result
// of checkNotNull()
}
I personally ignore the result of checkNotNull(), as above. And this makes things consistent with the other checks which return void.
The only advantage I see is that you can do something like that, but I find it less readable than doing it in two separate lines:
public String trim(String bar) {
return Preconditions.checkNotNull(bar).trim();
}
So, in short, I agree with you that the API is somewhat inconsistent, but I would prefer for all the methods to return void. A method should either have a side effect, or return something, but doing both should be avoided generally. Here, the goal of the method is to have a side effect: throwing an exception.
EDIT:
Your example is indeed a more valid explanation of why returning the argument is useful. But I would still have favored consistency and cleanness instead of this possibility of checking and assigning in a single line.
You can use valid4j with hamcrest-matchers instead (found on Maven Central as org.valid4j:valid4j)
For preconditions and postconditions:
import static org.valid4j.Assertive.*;
this.myField = require(argument, notNullValue());
this.myInteger = require(x, greaterThan(0));
...
return ensure(result, isValid());
For input validation:
import static org.valid4j.Validation.*;
validate(argument, isValid(), otherwiseThrowing(InvalidException.class));
Links:
http://www.valid4j.org/
https://github.com/helsing/valid4j

How to create dynamic IF statements? reflection?

Is it possible with reflection to create a dynamic IF statement?
I have seen examples with BeanShell (like this: Dynamic if statement evaluation problem with string comparison) but i would like to know if it was possible to do it without BeanShell, and be pointed to some examples to adapt to my needs.
Basically i have a statement of the form: A operator B.
A and B can be numbers (Doubles or ints) or strings, but always A is the same type as B.
operator can be !=, ==, >=, >, <= ,<, and even others which behavior may be defined trough a class of their own, another reason why i will use reflection, since i can take that string and use reflection to invoke the appropriate method.
I want (must) to avoid branching "if" and "switch" because the variations are too many and will change constantly with user generated input.
You can create a factory that returns the correct operator for the given input.
public class OperatorFactory {
private static final Map<String, Operator<?>> OPERATORS = new HashMap<String, Operator<?>>();
static {
OPERATORS.put("<Number", new LessThanNumOperator());
OPERATORS.put("==Number", new EqualToNumOperator());
OPERATORS.put("<String", new LessThanStringOperator());
...
}
public static Operator<?> getOperator(String someUserSpecifiedOp, Class<?> paramType) {
String key = someUserSpecifiedOp;
if (Number.class.isAssignableFrom(paramType)) {
key += "Number";
} else if (String.class.isAssignableFrom(paramType)) {
key += "String";
}
return OPERATORS.get(key);
}
}
public interface Operator<T> {
public boolean execute(T lhs, T rhs);
}
public class LessThanNumOperator implements Operator<Number> {
public boolean execute(Number lhs, Number rhs) {
return lhs.doubleValue() < rhs.doubleValue();
}
}
And then use it:
OperatorFactory.getOperator(userDesignatedOperation, lhs.getClass()).execute(lhs, rhs);
Reflection won't help. Reflection gives you information about your code structure (classes, methods, attributes), but it doesn't allow you to change and update existing code.
Don't try to generate new code, try instead of adding a way for users to change the behaviour of your app depending on their input.
I don't know exactly what you are trying to do. Post some examples of user input and expected behaviour to help narrow the options down. But here is a few things that might help you in your task:
Have a user interface that helps your user select the time of the operands, with text fields for values, and a dropdown box for the operator. Simple solution, but I wouldn't recommend it as it may add complexity to the user interface.
Write a parser for your expressions. Writting a simple parser for this very simple language (A operator B) should be doable in reasonable time.
Domain Specific Languages. Allows the users of your application to write some scripts that get interpreted by your application and respond in some way. You could imagine a DSL consisting in simple comparisons, and the results will influence the behaviour of your app. Have a look at Groovy, it is a good language for this use case.
You could make a interface like this
public interface MyComparator
{
public boolean matches(String operator);
public boolean compare(String a, String b);
}
Then you could make how many classes you want all implementing the interface like this
public class MyEquals implements MyComparator
{
#Override
public boolean matches(String operator)
{
return "==".equals(operator);
}
#Override
public boolean compare(String a, String b)
{
return a.equals(b);
}
}
and load them like this:
Class compClass = Class.forName(classname);
MyComparator comp = (MyComparator)compClass.newInstance();
you could so prepare a list of all available operators and iterate over it and even have the list of operators configured on a properties file.

Categories