AEM開発者ブログ by YAMATO

アドビ社のデリバリーパートナー大和株式会社のAEM開発者ブログです。

【Unit Test】JSONからResourceを作り出す

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」だそうです。お楽しみに。 僕も楽しみにしてます。