// 実行環境
* AdoptOpenJDK 11.0.9.1+1
* JUnit 5.7.0
* ArchUnit 0.14.1
アーキテクチャテストのモチベーション
特定の業務知識をもたない汎用的な値オブジェクトクラスやユーティリティクラスを common パッケージに置いていたら1、いつのまにか common パッケージ以外に依存してしまっていたなんてことはないでしょうか?これらの汎用クラスは外部から依存されることはあっても、外部に依存してはいけないはずです。
アーキテクチャテストの実装
package com.example;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaClass;
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.lang.syntax.ArchRuleDefinition.noClasses;
class ArchitectureTest {
// 検査対象のクラス
private static final JavaClasses CLASSES =
new ClassFileImporter()
.withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)
.importPackages("com.example");
@Test
void commonパッケージは特定の業務ドメインに依存しない() {
noClasses().that().resideInAPackage("com.example.domain.common..")
.should()
.dependOnClassesThat(new DescribedPredicate<>("common でないパッケージに属する") {
/**
* @param clazz 依存先のクラス
* @return 依存先のクラスが common でないパッケージに属するクラスである場合、true
*/
@Override
public boolean apply(final JavaClass clazz) {
if (! clazz.getPackageName().startsWith("com.example")) {
// サードパーティーライブラリなどへの依存はOK
return true;
}
return ! clazz.getPackageName().startsWith("com.example.domain.common");
}
})
.check(CLASSES);
}
}
-
そもそも common というくくりでパッケージングすることの是非も... ↩