ArchUnit для тестирования актуальной многоуровневой архитектуры
В настоящее время в нашем проекте мы реализовали многоуровневую архитектуру, в которой контроллер, служба, хранилище помещаются в один пакет для каждой функции, например:
- feature1:
- Feature1Controller
- Feature1Service
- Feature1Repository
- feature2:
- Feature2Controller
- Feature2Service
- Feature2Repository
Я нашел следующий пример модульного теста arch, где такие классы помещены в специальные пакеты https://github.com/TNG/ArchUnit-Examples/blob/master/example-junit5/src/test/java/com/tngtech/archunit/exampletest/junit5/LayeredArchitectureTest.java
Пожалуйста, предложите, есть ли возможность проверить многоуровневую архитектуру, когда все слои находятся в одном пакете
2 ответа
Если соглашения об именах файлов соблюдаются должным образом в вашем проекте, как насчет того, чтобы написать собственные тестовые примеры вместо использования layeredArchitecture()
.
Например:
classes().that().haveSimpleNameEndingWith("Service")
.should().onlyBeAccessed().byClassesThat().haveSimpleNameEndingWith("Controller")
noClasses().that().haveSimpleNameEndingWith("Service")
.should().accessClassesThat().haveSimpleNameEndingWith("Controller")
Я знаю, что этот вопрос довольно старый. Но, к сведению, некоторое время это было возможно с использованием предикатов для слоев, например
layeredArchitecture().consideringAllDependencies()
.layer("Controllers").definedBy(HasName.Predicates.nameEndingWith("Controller"))
.layer("Services").definedBy(HasName.Predicates.nameEndingWith("Service"))
.layer("Repository").definedBy(HasName.Predicates.nameEndingWith("Repository"))
.whereLayer("Controllers").mayNotBeAccessedByAnyLayer()
.whereLayer("Services").mayOnlyBeAccessedByLayers("Controllers")
.whereLayer("Repository").mayOnlyBeAccessedByLayers("Services")
Однако я не уверен, насколько хорошо это работает на практике. Потому что обычно у вас не просто есть классы, следующие этому шаблону именования, и все. Служба также может иметь некоторый POJO в качестве типа параметра метода (например,MyInput
) и это, возможно, не должно использоваться, например, в репозиториях. Кроме того, используя правила прямой зависимости (mayOnlyAccessLayers(..)
) это может привести к нежелательным нарушениям.