Skip to content

Instantly share code, notes, and snippets.

@mguilherme
Last active February 27, 2021 16:57
Show Gist options
  • Save mguilherme/745113e3ec30ffa1aa1fe720c7260400 to your computer and use it in GitHub Desktop.
Save mguilherme/745113e3ec30ffa1aa1fe720c7260400 to your computer and use it in GitHub Desktop.
ArchUnit Examples
// build.gradle.kts
// testImplementation("com.tngtech.archunit:archunit-junit5-engine:0.17.0")
@AnalyzeClasses(packages = ["my.awesome.package"])
class GeneralCodingRulesTest {
@ArchTest
val `no classes should throw generic exceptions` = NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS
@ArchTest
val `no classes should use JodaTime` = NO_CLASSES_SHOULD_USE_JODATIME
@ArchTest
val `interfaces should not have names ending with the word interface` = noClasses()
.that().areInterfaces()
.should().haveNameMatching(".*Interface")
@ArchTest
val `interfaces should not have simple class names containing the word interface` = noClasses()
.that().areInterfaces()
.should().haveSimpleNameContaining("Interface")
}
@AnalyzeClasses(packages = ["my.awesome.package"])
class LayerDependencyRulesTest {
@ArchTest
val `layer dependencies are respected` = layeredArchitecture()
.layer(APPLICATION_LAYER).definedBy("..application..")
.layer(DOMAIN_LAYER).definedBy("..domain..")
.layer(INFRASTRUCTURE_LAYER).definedBy("..infrastructure..")
.whereLayer(APPLICATION_LAYER).mayOnlyBeAccessedByLayers(INFRASTRUCTURE_LAYER)
.whereLayer(DOMAIN_LAYER).mayOnlyBeAccessedByLayers(APPLICATION_LAYER, INFRASTRUCTURE_LAYER)
.whereLayer(INFRASTRUCTURE_LAYER).mayOnlyBeAccessedByLayers(APPLICATION_LAYER)
companion object {
private const val APPLICATION_LAYER = "Application"
private const val DOMAIN_LAYER = "Domain"
private const val INFRASTRUCTURE_LAYER = "Infrastructure"
}
}
@AnalyzeClasses(
packages = ["my.awesome.package"],
importOptions = [ImportOption.DoNotIncludeTests::class]
)
class SpringCodingRulesTest {
@ArchTest
val `no classes should be annotated with autowired` = noFields()
.should().beAnnotatedWith(Autowired::class.java)
@ArchTest
val `no classes should be annotated with value` = noFields()
.should().beAnnotatedWith(Value::class.java)
@ArchTest
val `configuration classes should be annotated with Configuration annotation` = classes()
.that().haveSimpleNameEndingWith("Config")
.should().beAnnotatedWith(Configuration::class.java)
@ArchTest
val `classes with Configuration annotation should reside in configuration package` = classes()
.that().areAnnotatedWith(Configuration::class.java)
.should().resideInAPackage("..infrastructure.configuration")
}
@AnalyzeClasses(
packages = ["my.awesome.package.domain"],
importOptions = [ImportOption.DoNotIncludeTests::class]
)
class DomainCodingRules {
@ArchTest
val `classes in domain should not be annotated with Component annotation` = noClasses()
.should().beAnnotatedWith(Component::class.java)
.orShould().beMetaAnnotatedWith(Component::class.java)
@ArchTest
val `classes in domain should not use any spring classes` = noClasses()
.should().dependOnClassesThat()
.resideInAPackage("org.springframework..")
@ArchTest
val `classes in domain should not use any persistence classes` = noClasses()
.should().dependOnClassesThat()
.resideInAnyPackage("javax.persistence..", "org.hibernate..")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment