//Execution environment
* AdoptOpenJDK 11.0.9.1+1
* JUnit 5.7.0
* ArchUnit 0.14.1
https://dzone.com/articles/onion-architecture-is-interesting
package com.example;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.core.importer.ImportOption;
import org.junit.jupiter.api.Test;
import static com.tngtech.archunit.library.Architectures.onionArchitecture;
class ArchitectureTest {
//Class to be inspected
private static final JavaClasses CLASSES =
new ClassFileImporter()
.withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)
.importPackages("com.example");
@Test
void Architectural testing of onion architecture() {
onionArchitecture()
// domain.Define model package as domain model layer
.domainModels("com.example.domain.model..")
// domain.Define service package as domain service layer
.domainServices("com.example.domain.service..")
//Define application package as application service layer
.applicationServices("com.example.application..")
//Define infrastructure package as infrastructure adapter
.adapter("infra", "com.example.infrastructure..")
//Define presentation package as user interface adapter
.adapter("ui", "com.example.presentation..")
.check(CLASSES);
}
}
An example of a test failure assuming that an architecture violation was detected in which the Service class of the inner domain service layer depends on the UseCase class of the outer application service layer.
$ ./gradlew clean check
> Task :test FAILED
ArchitectureTest >Architecture testing of onion architecture() FAILED
java.lang.AssertionError: Architecture Violation [Priority: MEDIUM] - Rule 'Onion architecture consisting of
domain models ('com.example.domain.model..')
domain services ('com.example.domain.service..')
application services ('com.example.application..')
adapter 'infra' ('com.example.infrastructure..')
adapter 'ui' ('com.example.presentation..')' was violated (2 times):
Constructor <com.example.domain.service.employee.EmployeeRegisterService.<init>(com.example.application.HogeUseCase)> has parameter of type <com.example.application.HogeUseCase> in (EmployeeRegisterService.java:0)
Field <com.example.domain.service.employee.EmployeeRegisterService.hogeUseCase> has type <com.example.application.HogeUseCase> in (EmployeeRegisterService.java:0)
at com.tngtech.archunit.lang.ArchRule$Assertions.assertNoViolation(ArchRule.java:94)
at com.tngtech.archunit.lang.ArchRule$Assertions.check(ArchRule.java:82)
at com.tngtech.archunit.library.Architectures$LayeredArchitecture.check(Architectures.java:267)
at com.tngtech.archunit.library.Architectures$OnionArchitecture.check(Architectures.java:538)
at com.example.ArchitectureTest.Architecture testing of onion architecture(ArchitectureTest.java:560)
1 test completed, 1 failed
An example of a test failure assuming an architecture violation that the Controller class of the user interface adapter depends on the Repository (Impl) class of the infrastructure adapter.
$ ./gradlew clean check
> Task :test FAILED
ArchitectureTest >Architecture testing of onion architecture() FAILED
java.lang.AssertionError: Architecture Violation [Priority: MEDIUM] - Rule 'Onion architecture consisting of
domain models ('com.example.domain.model..')
domain services ('com.example.domain.service..')
application services ('com.example.application..')
adapter 'infra' ('com.example.infrastructure..')
adapter 'ui' ('com.example.presentation..')' was violated (2 times):
Constructor <com.example.presentation.employee.EmployeeController.<init>(com.example.infrastructure.datasource.EmployeeRepositoryImpl)> has parameter of type <com.example.infrastructure.datasource.EmployeeRepositoryImpl> in (EmployeeController.java:0)
Field <com.example.presentation.employee.EmployeeController.employeeRepository> has type <com.example.infrastructure.datasource.EmployeeRepositoryImpl> in (EmployeeController.java:0)
at com.tngtech.archunit.lang.ArchRule$Assertions.assertNoViolation(ArchRule.java:94)
at com.tngtech.archunit.lang.ArchRule$Assertions.check(ArchRule.java:82)
at com.tngtech.archunit.library.Architectures$LayeredArchitecture.check(Architectures.java:267)
at com.tngtech.archunit.library.Architectures$OnionArchitecture.check(Architectures.java:538)
at com.example.ArchitectureTest.Architecture testing of onion architecture(ArchitectureTest.java:560)
1 test completed, 1 failed
Recommended Posts