Closed JensPiegsa closed 7 years ago
I think there are several ways to test this. I don't know, if you really need the fluent API for this use case, so you could just do this test on a lower level: (for the case of simplicity, I'll assume that the simple name is unique and no class is called sth. like 'FooTestTest' or just 'Test')
@ArchTest
public static void test_classes_should_reside_in_the_correct_package(JavaClasses classes) {
Map<String, String> simpleTestNameToPackage = new HashMap<>();
// First collect all tests
for (JavaClass clazz : classes) {
if (clazz.getName().endsWith("Test")) {
simpleTestNameToPackage.put(clazz.getSimpleName(), clazz.getPackage());
}
}
// Then check for all classes that a possibly existing test is in the same package
for (JavaClass clazz : classes) {
String possibleTestName = clazz.getSimpleName() + "Test";
String correspondingTestPackage = simpleTestNameToPackage.get(possibleTestName);
boolean testExistsButIsInWrongPackage = correspondingTestPackage != null
&& !correspondingTestPackage.equals(clazz.getPackage());
if (testExistsButIsInWrongPackage) {
Assert.fail(String.format("Test class %s.%s is in the wrong package",
correspondingTestPackage, possibleTestName));
}
}
}
You'll probably have to refine this a little more, for example you could consider 'JavaClass.getSource()' to find out if the class you're checking is in main
or test
.
If you want to use the fluent API at all costs :wink: , you could initialize a custom condition by overriding init(..)
, and write it in the following way (the logic would be something similar to the low level case, I think)
classes().should(new ArchCondition<JavaClass>("have their test in the same package") {
@Override
public void init(Iterable<JavaClass> allClasses) {
// find all tests to begin with, and store them
}
@Override
public void check(JavaClass item, ConditionEvents events) {
// check every class with respect to the stored classes from init()
}
});
(of course it would look neater, if the condition was declared in a separate method)
Can you give me an update, if you were able to figure out your issue? (Because then I could close this issue :wink: )
Many thanks for coming back to this. Your provided solution is working for us!
After some refactorings, I want to ensure that all (.*)Test classes reside in the same package as their corresponding classes-under-test. How to achieve this with ArchUnit?