Custom assertion examples are missing
KroArtem opened this issue · comments
Hello, I was trying to make a custom assertion and looked through the documentation:
https://assertj.github.io/doc/#assertj-core-custom-assertions
It seems like this paragraph is missing.
There is an article here https://joel-costigliola.github.io/assertj/assertj-core-custom-assertions.html but it also seems to be a bit outdated.
While there is an example of extending an AbstractAssert
, it'd be nice to have an example of a AbstractIterableAssert
too.
I believe I can adopt an example from an old site but don't have enough knowledge to write about AbstractIterableAssert
as some things are unclear.
That's right, that paragraph has not been rewritten yet. However, https://joel-costigliola.github.io/assertj/assertj-core-custom-assertions.html should be a good starting point.
Is there anything specific you need help with?
@scordio , I had a lot of checks that required using method .usingElementComparatorIgnoringFields(...)
I thought it's a good reason to make a custom assertion. I've looked through an old article and
extended AbstractAssert
but then understood that it's required to extend AbstractIterableAssert
.
IDEA helped to override newAbstractIterableAssert
and toAssert
. These are the methods that maybe lack some documentation because it's not clear do they have to have additional logic.
My final assertion looks like this:
private static class StarredFolderListAssert extends AbstractIterableAssert<StarredFolderListAssert, List<StarredEntity>, StarredEntity, StarredFolderAssert> {
List<StarredEntity> entities = new ArrayList<>();
public StarredFolderListAssert(List<StarredEntity> starredEntities, Class<?> selfType) {
super(starredEntities, selfType);
entities.addAll(starredEntities);
}
@Override
protected StarredFolderListAssert newAbstractIterableAssert(Iterable iterable) {
return null;
}
public static StarredFolderListAssert assertThat(List<StarredEntity> actual) {
return new StarredFolderListAssert(actual, StarredFolderListAssert.class);
}
public StarredFolderListAssert containsStarredBaseInfo(StarredEntity entity) {
Assertions.assertThat(entities).usingElementComparatorIgnoringFields("setting", "starredAt", "parent").contains(entity);
return this;
}
@Override
protected StarredFolderAssert toAssert(StarredEntity value, String description) {
return null;
}
}
private static class StarredFolderAssert extends AbstractAssert<StarredFolderAssert, StarredEntity> {
public StarredFolderAssert(StarredEntity entity, Class<?> selfType) {
super(entity, selfType);
}
}
Maybe @joel-costigliola has something to add :)
In addition to the documentation, it would be great to have StarredEntity
and StarredFolder
code so that we can add you example example in assertj-examples.
@scordio , @joel-costigliola , that was a long delay from me, but here it is:
@Data
@AllArgsConstructor
@Builder
public static class StarredEntity {
Integer id;
String title;
Boolean isProject;
Long starredAt;
Settings setting;
Long order;
}
I wanted to ignore several fields that's why a custom assertion was written. However, it was not clear what does newAbstractIterableAssert
and toAssert
methods do?
I have migrated the documentation of the old site to the new one. see https://assertj.github.io/doc/#assertj-core-custom-assertions.
@KroArtem is used by navigation method like first()
that returns assertions for the first element of the iterable.
In your case simply build a StarredFolderAssert
.
newAbstractIterableAssert
is used to build the assert instance with a filtered iterable (basically after filteredOn
is called), simply create another instance of your own iterable assert with the given iterable.
Ex:
@Override
protected StarredFolderListAssert newAbstractIterableAssert(Iterable iterable) {
return new StarredFolderListAssert(new ArrayList<>(iterable), StarredFolderListAssert.class);
}
We will add javadoc for both newAbstractIterableAssert
and toAssert
.
Note that you could inherit from AbstractListAssert
since it looks like you want to assert on List<StarredEntity>
Thanks! I think this ticket can be closed now.