Files
JUnit_Tutorials/archunit/docs/output/01-layering-violation-failure.txt
T

47 lines
3.6 KiB
Plaintext

Captured from a real `mvn test` run with a temporary class added to the controller
package, com.ankurm.tutorials.junit.archunit.controller.BadOrderLookupController,
whose constructor took OrderRepository directly instead of going through
OrderStatusService. The class was deleted immediately after this run; it exists
only in this transcript and in the "before/after" diagram in the published post.
[INFO] Running com.ankurm.tutorials.junit.archunit.LayeredArchitectureTest
[ERROR] Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.445 s <<< FAILURE! -- in com.ankurm.tutorials.junit.archunit.LayeredArchitectureTest
[ERROR] LayeredArchitectureTest.controllersOnlyCallServicesWhichOnlyCallRepositories -- Time elapsed: 1.402 s <<< FAILURE!
java.lang.AssertionError:
Architecture Violation [Priority: MEDIUM] - Rule 'Layered architecture considering all dependencies, consisting of
layer 'Controller' ('..controller..')
layer 'Service' ('..service..')
layer 'Repository' ('..repository..')
where layer 'Controller' may not be accessed by any layer
where layer 'Service' may only be accessed by layers ['Controller']
where layer 'Repository' may only be accessed by layers ['Service']' was violated (3 times):
Constructor <com.ankurm.tutorials.junit.archunit.controller.BadOrderLookupController.<init>(com.ankurm.tutorials.junit.archunit.repository.OrderRepository)> has parameter of type <com.ankurm.tutorials.junit.archunit.repository.OrderRepository> in (BadOrderLookupController.java:0)
Field <com.ankurm.tutorials.junit.archunit.controller.BadOrderLookupController.orderRepository> has type <com.ankurm.tutorials.junit.archunit.repository.OrderRepository> in (BadOrderLookupController.java:0)
Method <com.ankurm.tutorials.junit.archunit.controller.BadOrderLookupController.rawStatus(java.lang.String)> calls method <com.ankurm.tutorials.junit.archunit.repository.OrderRepository.findStatus(java.lang.String)> in (BadOrderLookupController.java:25)
at com.tngtech.archunit.lang.ArchRule$Assertions.assertNoViolation(ArchRule.java:94)
at com.tngtech.archunit.lang.ArchRule$Assertions.check(ArchRule.java:86)
at com.tngtech.archunit.library.Architectures$LayeredArchitecture.check(Architectures.java:347)
at com.tngtech.archunit.junit.internal.ArchUnitTestDescriptor$ArchUnitRuleDescriptor.execute(ArchUnitTestDescriptor.java:168)
at com.tngtech.archunit.junit.internal.ArchUnitTestDescriptor$ArchUnitRuleDescriptor.execute(ArchUnitTestDescriptor.java:151)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
[INFO] Results:
[ERROR] Tests run: 3, Failures: 1, Errors: 0, Skipped: 0
[INFO] BUILD FAILURE
Three things worth noticing in this message:
1. ArchUnit reports all THREE offending facts about the one bad class in a single
violation group: the constructor parameter, the field it gets assigned to, and
the actual method call that crosses the layer boundary. One bad wire gets
reported three ways because ArchUnit checks dependency *existence*, not just
call sites -- the field and the constructor parameter are both "access" on
their own, even on a line that never executes.
2. The file:line at the end of each fact (BadOrderLookupController.java:25) points
at real source positions ArchUnit extracted from the compiled .class file's
debug info, not from parsing the .java file.
3. "Priority: MEDIUM" is the rule's declared priority, not a severity the test
assigns at failure time -- layeredArchitecture() rules default to MEDIUM, and
a build can be configured to fail the whole run only above a given priority.