AEM Developerの皆様お疲れさまです。大和株式会社の狩野です。
Qiitaのアドベントカレンダーに便乗して始めた記事投稿イベント2日目です。 今日2日目の内容は、単体テスト用のResourceをJSONから作り出す方法についてです。
1日目の記事→AEM標準APIのNPE対策
コンポーネントのダイアログ入力値を扱うJavaクラスの単体テストを行う時、ValueMapDecorator クラス等でMock用のpropertiesを作るのも良いですが、
もっと簡単にページのノード構造をjsonファイルとして保存しておき、それを単体テストの入力値に使う事もできます。
これの利点は、複数のテストクラスで使い回すことが可能なところと、AEM側から取得が簡単なところです。
事前準備
pom.xml
ルートのpom.xmlに以下の依存関係を追加します。
<dependency> <groupId>io.wcm</groupId> <artifactId>io.wcm.testing.aem-mock.junit5</artifactId> <version>2.5.2</version> <scope>test</scope> </dependency>
次に、core配下のpom.xmlに以下の依存関係を追加します。
<dependency> <groupId>io.wcm</groupId> <artifactId>io.wcm.testing.aem-mock.junit5</artifactId> </dependency>
jsonファイルの用意
src/test/resources/[テストを行うクラスが格納されているpackageのパス]/ 配下に以下のjsonファイルを作成する。
今回の例では、src/test/resources/com/adobe/aem/guides/yamato/core/models/form/form-page.json にファイルを作成する。
このjsonは、テスト用プロパティを入力したページに http://localhost:4502/content/yamato/jp/ja/path/to/page.infinity.json という形式でアクセスすれば取得可能です。以下に一部を載せます。
"advantage": {
"jcr:primaryType": "cq:Page",
"jcr:content": {
"jcr:primaryType": "cq:PageContent",
"jcr:title": "私達の特長",
"sling:resourceType": "yamato/components/structure/page"
}
}
テストの実装
①テストクラスに @ExtendWith アノテーションを付与し、引数に AemContextExtension.class を与える
io.wcm.testing.mock.aem.junit5.AemContextExtension
import org.junit.jupiter.api.extension.ExtendWith; import io.wcm.testing.mock.aem.junit5.AemContext; import io.wcm.testing.mock.aem.junit5.AemContextExtension; @ExtendWith(AemContextExtension.class) class TutorialTest { }
② AemContext クラスのフィールドを宣言する
io.wcm.testing.mock.aem.junit5.AemContext
import org.junit.jupiter.api.extension.ExtendWith; import io.wcm.testing.mock.aem.junit5.AemContext; import io.wcm.testing.mock.aem.junit5.AemContextExtension; @ExtendWith(AemContextExtension.class) class TutorialTest { private final AemContext ctx = new AemContext(); }
③ AemContext.load().json() メソッドで準備したjsonを読み込む
@BeforeEach public void setUp() { ctx.addModelsForClasses(CurrentFlow.class); ctx.load().json("/com/adobe/aem/guides/yamato/core/models/form/form-page.json", "/content/yamato/jp/ja/"); }
こう宣言することによって、ctxオブジェクト内ではJsonファイルのルートが/content/yamato/jp/jaというパスに設定されるようになる。
ここでの指定と、Jsonの構造をうまく書けばAEMと同等の構造をテストコード上で扱うことができ、非常に便利。
④ currentResource() メソッドでノードをresourceオブジェクトに変換し、getValueMap()メソッドでpropertiesを取得できるので、あとは好きなようにテストする。
final ValueMap pageProperties = ctx.currentResource("/content/yamato/jp/ja/jcr:content").getValueMap();
currentResource() メソッドはこういう風に ValueMap を返すメソッドにも使えるが、以下のようにJSONから作り出した Resource を元にテスト対象となるSling Modelsのインスタンスを作り出すことも可能です。
Tutorial t = ctx.request().adaptTo(Tutorial.class);
こちらの使い方について詳しくはWKND Tutorial - Unit Testingに書かれているので参照ください。
最後に
以上となります。明日は青葉さんが執筆します。内容は「コアコンポーネント:trackingFeature」だそうです。お楽しみに。 僕も楽しみにしてます。