Skip to content

Instantly share code, notes, and snippets.

@almondtools
Created June 5, 2018 07:00
Show Gist options
  • Save almondtools/b884900746cb2028886f50039a30d397 to your computer and use it in GitHub Desktop.
Save almondtools/b884900746cb2028886f50039a30d397 to your computer and use it in GitHub Desktop.
Proposal how to enhance assertj collection matching
package test;
import static java.util.Objects.isNull;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import java.util.ArrayList;
import java.util.List;
import org.assertj.core.api.HamcrestCondition;
import org.hamcrest.Matcher;
import org.hamcrest.core.IsNull;
import org.junit.jupiter.api.Test;
public class AssertJCollectionExample {
/*
* + keeps sequence
* - depends on indexes (will not work for sets, sorted sets, queues, iterators)
*/
@Test
void testListIndexMisuse() throws Exception {
List<ComplexObject> list = createList();
// this will not work!
// assertThat(list).element(0).extracting(ComplexObject::getValue).isEqualTo("get0");
assertThat(list).extracting(ComplexObject::getValue).element(0).isEqualTo("get0");
assertThat(list).extracting(ComplexObject::getFixedCounter).element(0).isEqualTo(0);
assertThat(list).extracting(ComplexObject::getValue).element(1).isEqualTo("get1");
assertThat(list).extracting(ComplexObject::getFixedCounter).element(1).isEqualTo(0);
assertThat(list).extracting(ComplexObject::getValue).element(2).isEqualTo("get2");
assertThat(list).extracting(ComplexObject::getFixedCounter).element(2).isEqualTo(2);
}
/*
* + not depending on indexes
* - does not assert that each element is matched at least by one assertion
*/
@Test
void testListAnyMisuse() throws Exception {
List<ComplexObject> list = createList();
assertThat(list).anySatisfy(element -> {
assertThat(element.getValue()).isEqualTo("get0");
assertThat(element.getFixedCounter()).isEqualTo(0);
});
assertThat(list).anySatisfy(element -> {
assertThat(element.getValue()).isEqualTo("get1");
assertThat(element.getFixedCounter()).isEqualTo(0);
});
assertThat(list).anySatisfy(element -> {
assertThat(element.getValue()).isEqualTo("get2");
assertThat(element.getFixedCounter()).isEqualTo(2);
});
}
/*
* - does only assert common properties
*/
@Test
void testListAllMisuse() throws Exception {
List<ComplexObject> list = createList();
assertThat(list).allSatisfy(element -> {
assertThat(element.getValue()).startsWith("get");
assertThat(element.getFixedCounter()).isGreaterThanOrEqualTo(0);
});
}
/*
* + not depending on indexes
* + keeping sequence property
* - not fluent
* - type safety warning
* - mismatch description is hard for custom matchers
*/
@Test
void testListConditions() throws Exception {
List<ComplexObject> list = createList();
assertThat(list).has(new HamcrestCondition(containsInAnyOrder(
matches("get0", 0),
matches("get1", 0),
matches("get2", 2)
)));
}
private Matcher<ComplexObject> matches(String value, int fixedCounter) {
// TODO replace with a matcher that matches value an fixedCounter
return IsNull.notNullValue(ComplexObject.class);
}
@Test
void testCouldThisWork() throws Exception {
List<ComplexObject> list = createList();
assertThat(list).satisfyInOrder(element -> {
assertThat(element.getValue()).isEqualTo("get0");
assertThat(element.getFixedCounter()).isEqualTo(0);
}, element -> {
assertThat(element.getValue()).isEqualTo("get1");
assertThat(element.getFixedCounter()).isEqualTo(0);
}, element -> {
assertThat(element.getValue()).isEqualTo("get2");
assertThat(element.getFixedCounter()).isEqualTo(2);
});
}
private List<ComplexObject> createList() {
List<ComplexObject> list = new ArrayList<>();
list.add(createObject(0, false));
list.add(createObject(1, false));
list.add(createObject(2, true));
return list;
}
private ComplexObject createObject(int gets, boolean fix) {
ComplexObject get = new ComplexObject("get" + gets);
for (int i = 0; i < gets; i++) {
get.getValue();
}
if (fix) {
get.fix();
}
return get;
}
private static class ComplexObject {
private String value;
private int fixedCounter;
private int getCounter;
public ComplexObject(String value) {
this.value = value;
}
public String getValue() {
getCounter++;
return value;
}
public void fix() {
this.fixedCounter = getCounter;
}
public int getFixedCounter() {
return fixedCounter;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment