Created
June 5, 2018 07:00
-
-
Save almondtools/b884900746cb2028886f50039a30d397 to your computer and use it in GitHub Desktop.
Proposal how to enhance assertj collection matching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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