I'm trying to write an ArchUnit test which tests if a certain unchecked exception when thrown is also declared by that method, and recursively, if any method calling that method also declares it.
The intention is to ensure these exceptions are documented everywhere, and, since I can enforce anything that is declared to be thrown has to be documented (other tools can enforce this), this seemed a good way to go about it.
The scope of these checks can be limited to a certain package; ie. treat runtime exception X when used within package Y as a "checked" exception, and enforce it with a rule.
Passing code:
void someMethod() throws MyRunTimeException {
throws new MyRunTimeException();
}
void anotherMethod() throws MyRunTimeException {
someMethod();
}
Failing code:
void someMethod() { // doesn't declare exception
throws new MyRunTimeException();
}
void anotherMethod() { // should declare exception when someMethod declares it
someMethod();
}
Now I think I can detect methods that do not declare the exception as follows:
noMethods().should().declareThrowableOfType(MyRunTimeException.class)
And I think I can detect calls to create this exception (even better would be when it is actually thrown, but I couldn't find that):
noClasses().should().callConstructorWhere(
target(is(declaredIn(MyRunTimeException.class)))
.and(not(originOwner(is(assignableTo(MyRunTimeException.class)))))
);
... but I see no way how I could combine these two rules.
For some reason however ArchUnit only allows checking calls from classes, but not from methods (which seems to make more sense). In other words, I couldn't find a way to check calls given a method:
noMethods().should().callConstructorWhere( ... )
Or:
noMethods().should().throw(MyRuntimeException.class)
.and(not(declareThrowableOfType(MyRunTimeException.class)))
Any idea how I could go about enforcing such a rule?