ArchUnit
ArchUnit copied to clipboard
How to verify that a method is wrapped with try-with-resources?
This is just a question. Is it possible to write an arch unit test that verifies that calls for certain methods are always wrapped with try-with-resources?
The method:
Stream<User> findAllByCustomQueryAndStream();
Compliant call:
try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) {
//do something with stream
}
Non-compliant call:
Stream<User> stream = repository.findAllByCustomQueryAndStream();
//do something with stream
Context: Spring repository methods that return Stream should be wrapped by a try-with-resources block, as suggested by the official docs.
I have tried inspecting the TryCatchBlock object but it does not give me information on what's actually being wrapped, it only contains info on the //do something with stream block and the caught exceptions.
I don't it's currently possible to assert exactly what you want. What you could do, and what might be close enough to catch the majority of "whoops, I forgot about closing the stream" errors, would be to check that all callers of your repository method also call Stream.close() within the same method.
Basically something like
methods()
.that().areDeclaredInClassesThat().haveSimpleNameEndingWith("Repository")
.and().haveRawReturnType(Stream.class)
.should().onlyBeCalled().byCodeUnitsThat(DescribedPredicate.describe("call Stream.close()", callToRepositoryMethod ->
callToRepositoryMethod.getMethodCallsFromSelf().stream()
.map(JavaAccess::getTarget)
.anyMatch(AccessTarget.Predicates.declaredIn(Stream.class).and(HasName.Predicates.name("close")))
))
.as("Classes calling Repository methods that return Streams should also close those Streams "
+ "(preferably by using try-with-resources, see "
+ "https://docs.spring.io/spring-data/jpa/reference/repositories/query-methods-details.html#repositories.query-streaming)")