Open yeikel opened 2 years ago
For context, we had outlined some specifics around this migration. We ended up closing the issue because we did not have the resources to work on it at the time.
https://github.com/openrewrite/rewrite-testing-frameworks/issues/16
One thing that might make sense is the straightforward migration of assertThat(foo, instanceOf(Foo.class))
to JUnit5 assertInstanceOf(Foo.class, foo)
.
That would provide a framework-independent migration, potentially lowering dependencies on Hamcrest for JUnit5 users.
@rovarga That would indeed make sense as a starting point; is that something you'd be willing to contribute with some guidance? I suspect there's quite a few more in #16 that are easy to tackle once an initial sample recipe is available.
@rovarga That would indeed make sense as a starting point; is that something you'd be willing to contribute with some guidance? I suspect there's quite a few more in #16 that are easy to tackle once an initial sample recipe is available.
Yes I would certainly be interested, unfortunately I do not have the cycles right now. Perhaps in a couple of weeks (I will keep this on my radar).
Glad to hear you're interested in helping out! Let us know how we can best support you. I'll pitch a quick outline right now.
Looking through the list in #16 I'm seeing quite a few matchers that have one to one replacements in AssertJ, which might be the easiest to tackle. Assuming here that people picked Hamcrest for the fluent matchers, and then AssertJ is the most direct replacement to that.
Alternatively we can (only) migrate to JUnit 5, and then optionally after that chain the existing migration from JUnit 5 to AssertJ; that way we can have both, provided there's equivalents for all matchers in both JUnit 5 and AssertJ, and recipes to go between those.
Either way I suppose you can start by creating a recipe that takes in two options:
org.hamcrest.Matchers equalTo
.org.assertj.core.api.AbstractAssert isEqualTo
The recipe can then match on the first method pattern, and replace the surrounding org.hamcrest.MatcherAssert.assertThat
with a call to org.assertj.core.api.Assertions.assertThat
with the same first argument, and using the hamcrest matcher argument in a chained call to the replacement method.
-org.hamcrest.MatcherAssert.assertThat(actual, equalTo(expected));
+org.assertj.core.api.Assertions.assertThat(actual).isEqualTo(expected);
or alternatively for JUnit 5
-org.hamcrest.MatcherAssert.assertThat(actual, equalTo(expected));
+org.junit.jupiter.api.Assertions.assertEquals(expected, actual);
Of course with appropriate new imports, removing the old imports, and using JavaTemplate to select the correct overloaded method where applicable for AssertJ. There should be plenty of examples to see how to achieve that, even if it can be daunting at first.
With the above you'd then be able to convert quite a few similar Hamcrest matchers using a single recipe, by configuring the options in a yaml recipe file. That way you'll have maximum output from a single Java recipe.
Anything the generic recipe can not handle, can then be picked up separately in a dedicated recipe for that use case. We prefer to maintain multiple relatively simple recipes, rather than one recipe to migrate all use cases.
Hope this helps!
While the Hamcrest repo is still active, the latest release is from Oct 16, 2019
I think that this is a potential good use case for a migration recipe
We could have two different types of migration recipes (and issues)
Relevant discussion : https://github.com/hamcrest/JavaHamcrest/issues/353