Skip to content

Hamcrest to AssertJ unhandled cases (instanceOf, hasProperty and hasItem) #915

@gwydi

Description

@gwydi

What problem are you trying to solve?

We are using the migratehamcresttoassertj recipe to migrate multiple repositories from Hamcrest to AssertJ. There is still a large number of tests, that could not be migrated automatically. Here are some of those cases.

TLDR; instanceOf, hasProperty and hasItem are not migrated, it would be very handy if they were.

If you like i can also split them into individual issues.

hasProperty(string)

assertThat(object, 
  hasProperty(
    is(value)
  )
)

Not migrated at all.

allOf(hasItem())

assertThat(someList, allOf(
  hasItem(item),
  hasItem(item),
));

becomes

assertThat(someList)
  .satisfies(
    arg -> assertThat(arg).contains(item)
    arg -> assertThat(arg).contains(item)
  );

this also leads to a compile time error: Cannot resolve method 'contains([Type of item in list])'

assertThat(list, hasItem(allOf(hasProperty(is()))))

assertThat(someList, hasItem(
  allOf(
    hasProperty(string, is(value)),
    hasProperty(string, is(value))
  )
))

becomes

assertThat(someList).contains(
  allOf(
    hasProperty(string, is(value)),
    hasProperty(string, is(value))
  )
)

assertThat are migrated, allOf and hasProperty are not migrated.
This also leads to a compile time error because of the mixture between AssertJ and Hamcrest.

assertThat(object, allOf(hasProperty(is())))

assertThat(object, 
  allOf(
    hasProperty(string, is(value)),
    hasProperty(string, is(value))
  )
)

becomes

org.assertj.core.api.Assertions.assertThat(object)
  .satisfies(
    arg -> assertThat(arg, hasProperty(string, is(value))),
    arg -> assertThat(arg, hasProperty(string, is(value)))
  )
)

Outer assertThat as well as allOf are migrated, inner assertThat and hasProperty are not migrated.

instanceOf()

assertThat(list, hasItem(instanceOf(Type)))
assertThat(list, everyItem(instanceOf(Type)))

are not migrated at all.

Not replacing org.hamcrest.MatcherAssert.assertThat static import

In the case where not all Hamcrest asserts can be replaced, the static import is also not replaced and all new AssertJ assertThat' calls have to use the fully qualified path.
If you want to fix issues that arose by hand, you still have to adjust all the asserts which were successful in the affected files.

Describe the solution you'd like

hasProperty(string)

assertThat(object)
    .extracting("propertyName")
    .isEqualTo(value);

Or even better use the getter method if available.

allOf(hasItem())

assertThat(someList).contains(
  item,
  item
);

assertThat(list, hasItem(allOf(hasProperty(is()))))

assertThat(someList)
  .anySatisfy(item -> {
    assertThat(item).extracting(string).isEqualTo(value);
    assertThat(item).extracting(string).isEqualTo(value);
  });

This should probably be the easiest solution, but there are many other options for how this could be migrated.

assertThat(object, allOf(hasProperty(is())))

assertThat(object)
  .satisfies(arg -> {
    assertThat(arg).extracting(string).isEqualTo(value);
    assertThat(arg).extracting(string).isEqualTo(value);
  });

Same as above, there would be much cleaner ways to migrate this, but this is probably the closest.

instanceOf()

assertThat(list).hasAtLeastOneElementOfType(XXX.class);
assertThat(list).hasOnlyElementsOfType(XXX.class);

Not replacing org.hamcrest.MatcherAssert.assertThat static import

Use fully quallified calls for Hamcrest, not the new AssertJ calls.

Have you considered any alternatives or workarounds?

Alternative is fixing those issues by hand, which is quite a large task in our case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions