package com.tngtech.archunit.integration.junit; import com.tngtech.archunit.example.SomeMediator; import com.tngtech.archunit.example.controller.one.UseCaseOneController; import com.tngtech.archunit.example.controller.two.UseCaseTwoController; import com.tngtech.archunit.example.persistence.layerviolation.DaoCallingService; import com.tngtech.archunit.example.service.ServiceViolatingLayerRules; import com.tngtech.archunit.exampletest.junit.LayeredArchitectureTest; import com.tngtech.archunit.junit.AnalyzeClasses; import com.tngtech.archunit.junit.ArchTest; import com.tngtech.archunit.junit.ArchUnitIntegrationTestRunner; import com.tngtech.archunit.junit.ExpectedViolation; import com.tngtech.archunit.lang.ArchRule; import org.junit.runner.RunWith; import static com.tngtech.archunit.junit.ExpectedViolation.from; import static java.lang.System.lineSeparator; @RunWith(ArchUnitIntegrationTestRunner.class) @AnalyzeClasses(packages = "com.tngtech.archunit.example") public class LayeredArchitectureIntegrationTest { @ArchTest @ExpectedViolationFrom(location = LayeredArchitectureIntegrationTest.class, method = "expectLayerViolations") public static final ArchRule layer_dependencies_are_respected = LayeredArchitectureTest.layer_dependencies_are_respected; static void expectLayerViolations(ExpectedViolation expectViolation) { expectViolation.ofRule("Layered architecture consisting of" + lineSeparator() + "layer 'Controllers' ('com.tngtech.archunit.example.controller..')" + lineSeparator() + "layer 'Services' ('com.tngtech.archunit.example.service..')" + lineSeparator() + "layer 'Persistence' ('com.tngtech.archunit.example.persistence..')" + lineSeparator() + "where layer 'Controllers' may not be accessed by any layer" + lineSeparator() + "where layer 'Services' may only be accessed by layers ['Controllers']" + lineSeparator() + "where layer 'Persistence' may only be accessed by layers ['Services']") .byCall(from(DaoCallingService.class, "violateLayerRules") .toMethod(ServiceViolatingLayerRules.class, "doSomething") .inLine(13)) .byCall(from(SomeMediator.class, "violateLayerRulesIndirectly") .toMethod(ServiceViolatingLayerRules.class, "doSomething") .inLine(15)) .byCall(from(ServiceViolatingLayerRules.class, "illegalAccessToController") .toConstructor(UseCaseTwoController.class) .inLine(12)) .byCall(from(ServiceViolatingLayerRules.class, "illegalAccessToController") .toMethod(UseCaseTwoController.class, "doSomethingTwo") .inLine(13)) .byAccess(from(ServiceViolatingLayerRules.class, "illegalAccessToController") .getting().field(UseCaseOneController.class, "someString") .inLine(11)); } }