{"id":17754957,"url":"https://github.com/mehmetpekdemir/spring-boot-archunit","last_synced_at":"2026-04-11T21:09:20.137Z","repository":{"id":93754588,"uuid":"399568957","full_name":"mehmetpekdemir/spring-boot-archunit","owner":"mehmetpekdemir","description":"Spring boot ArchUnit","archived":false,"fork":false,"pushed_at":"2021-08-24T19:40:32.000Z","size":8,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-03-01T07:32:43.652Z","etag":null,"topics":["archunit","java11","spring-boot","testing"],"latest_commit_sha":null,"homepage":"https://github.com/mehmetpekdemir/spring-boot-archunit","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mehmetpekdemir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-24T18:36:22.000Z","updated_at":"2022-03-11T11:16:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"88f1f157-3072-466f-9243-a95510b91487","html_url":"https://github.com/mehmetpekdemir/spring-boot-archunit","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mehmetpekdemir%2Fspring-boot-archunit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mehmetpekdemir%2Fspring-boot-archunit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mehmetpekdemir%2Fspring-boot-archunit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mehmetpekdemir%2Fspring-boot-archunit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mehmetpekdemir","download_url":"https://codeload.github.com/mehmetpekdemir/spring-boot-archunit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246628229,"owners_count":20808106,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["archunit","java11","spring-boot","testing"],"created_at":"2024-10-26T14:42:28.829Z","updated_at":"2025-10-30T06:03:22.232Z","avatar_url":"https://github.com/mehmetpekdemir.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ArchUnit\n\n- ArchUnit is a free, simple and extensible library for checking the architecture of your Java code. \n- That is, ArchUnit can check dependencies between packages and classes, layers and slices, check for cyclic dependencies and more. \n- It does so by analyzing given Java bytecode, importing all classes into a Java code structure. \n- ArchUnit's main focus is to automatically test architecture and coding rules, using any plain Java unit testing framework.\n\n### Import maven dependency\n\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.tngtech.archunit\u003c/groupId\u003e\n        \u003cartifactId\u003earchunit-junit5\u003c/artifactId\u003e\n        \u003cversion\u003e${archunit.version}\u003c/version\u003e\n        \u003cscope\u003etest\u003c/scope\u003e\n    \u003c/dependency\u003e\n\n### Create a test class\n\n    class ArchunitApplicationTests {\n\n          private JavaClasses importedClasses;\n\n          @BeforeEach\n          void setup() {\n              importedClasses = new ClassFileImporter()\n                    .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)\n                    .importPackages(\"com.springboot.testing.archunit\");\n          }\n     }\n\n### Annotations checks\n\n    @Test\n    void field_injection_not_use_autowired_annotation() {\n        noFields()\n                .should().beAnnotatedWith(Autowired.class)\n                .check(importedClasses);\n    }\n\n    @Test\n    void repository_classes_should_have_spring_repository_annotation() {\n        classes()\n                .that().resideInAPackage(\"..repository..\")\n                .should().beAnnotatedWith(Repository.class)\n                .check(importedClasses);\n    }\n\n    @Test\n    void service_classes_should_have_spring_service_annotation() {\n        classes()\n                .that().resideInAPackage(\"..service..\")\n                .should().beAnnotatedWith(Service.class)\n                .check(importedClasses);\n    }\n\n### Package Dependency Checks\n\n    @Test\n    void services_and_repositories_should_not_depend_on_controller() {\n        noClasses()\n                .that().resideInAnyPackage(\"com.springboot.testing.archunit.service..\")\n                .or().resideInAnyPackage(\"com.springboot.testing.archunit.repository..\")\n                .should()\n                .dependOnClassesThat()\n                .resideInAnyPackage(\"com.springboot.testing.archunit.controller..\")\n                .because(\"Services and repositories should not depend on web layer\")\n                .check(importedClasses);\n    }\n\n### Class Dependency Checks\n\n    @Test\n    void service_classes_should_only_be_accessed_by_controller() {\n        classes()\n                .that().resideInAPackage(\"..service..\")\n                .should().onlyBeAccessed().byAnyPackage(\"..service..\", \"..controller..\")\n                .check(importedClasses);\n    }\n\n    @Test\n    void repository_classes_should_only_be_accessed_by_service() {\n        classes()\n                .that().resideInAPackage(\"..repository..\")\n                .should().onlyBeAccessed().byAnyPackage(\"..repository..\", \"..service..\")\n                .check(importedClasses);\n    }\n\n### Naming convention\n\n    @Test\n    void service_classes_should_be_named_blabla_service() {\n        classes()\n                .that().resideInAPackage(\"..service..\")\n                .should().haveSimpleNameEndingWith(\"Service\")\n                .check(importedClasses);\n    }\n\n    @Test\n    void repository_classes_should_be_named_blabla_repository() {\n        classes()\n                .that().resideInAPackage(\"..repository..\")\n                .should().haveSimpleNameEndingWith(\"Repository\")\n                .check(importedClasses);\n    }\n\n    @Test\n    void controller_classes_should_be_named_blabla_controller() {\n        classes()\n                .that().resideInAPackage(\"..controller..\")\n                .should().haveSimpleNameEndingWith(\"Controller\")\n                .check(importedClasses);\n    }\n\n### Layer Dependency Rules Test\n\n    @Test\n    void layered_architecture_should_be_respected() {\n        layeredArchitecture()\n                .layer(\"Controller\").definedBy(\"..controller..\")\n                .layer(\"Service\").definedBy(\"..service..\")\n                .layer(\"Repository\").definedBy(\"..repository..\")\n\n                .whereLayer(\"Controller\").mayNotBeAccessedByAnyLayer()\n                .whereLayer(\"Service\").mayOnlyBeAccessedByLayers(\"Controller\")\n                .whereLayer(\"Repository\").mayOnlyBeAccessedByLayers(\"Service\")\n                .check(importedClasses);\n    }\n\n    @Test\n    void repositories_must_reside_in_repository_package() {\n        classes().that()\n                .haveNameMatching(\".*Repository\").should().resideInAPackage(\"..repository..\")\n                .as(\"Repositories should reside in a package '..repository..'\")\n                .check(importedClasses);\n    }\n\n    @Test\n    void services_must_reside_in_service_package() {\n        classes().that()\n                .haveNameMatching(\".*Service\").should().resideInAPackage(\"..service..\")\n                .as(\"Services should reside in a package '..service..'\")\n                .check(importedClasses);\n    }\n\n    @Test\n    void entity_classes_should_be_public() {\n        classes()\n                .that().resideInAPackage(\"..entity..\")\n                .should()\n                .bePublic()\n                .check(importedClasses);\n    }\n\n### License\n- Distributed under the MIT License. See [LICENSE](LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmehmetpekdemir%2Fspring-boot-archunit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmehmetpekdemir%2Fspring-boot-archunit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmehmetpekdemir%2Fspring-boot-archunit/lists"}