AEM 6.3, wcm.io: sling MockResource null в методе @Activate

У меня есть служба OSGI, которая имеет метод @Activate. В методе активации я вызываю метод buildTitleList, где запрашиваю некоторые ресурсы (страницы) и собираю их заголовки в список. Этот код работает в работающей среде, но не в моих модульных тестах.

Я создаю страницу в моем контексте следующим образом:

aemContext.create().page("/content/test-page', "/apps/platform-company/templates/home-page", "test-tile");

Если я отлаживаю свой модульный тест, я вижу, что ресурсы, которые я запрашиваю в 'buildTitleList', пусты (примечание: я уверен, что мой путь указан правильно)

Когда я вызываю buildTitleList непосредственно в моем модульном тесте, он работает. Это нормальное поведение, есть ли способ убедиться, что метод @Activate также может видеть вновь созданную страницу в контексте?

Тестовое задание:

@Test
public void checkTitles() {
    TitleService titleService = context.getService(TitleService.class);
    System.out.println(); //If I set a breakpoint here and look into the TitleService instance the list of titles is still 0
}

TitleService:

public class TitleService {

    private List<String> titles;

    public TitleService() {
        this.titles = new CopyOnWriteArrayList<>();
    }

    ...
    public void buildTitleList() throws RepositoryException, LoginException, WCMException {

        // Gather title code here (incl. newlist). This works on a running instance but the resoure is always null when calle from within an @Activa method

        this.titles.addAll(newlist);

    }
    ...

    @Activate
    protected void Activate() {
        buildTitleList();       
    }
}

Код настройки:

...

public static AemContext getAemContext(RunMode runMode) {
    if (aemContext != null) {
        aemContext.runMode(runMode.getValue());
        return aemContext;
    } else {
        aemContext = newAemContext();
        aemContext.runMode(runMode.getValue());
        return aemContext;
    }
}

public static AemContext newAemContext() {
    return new AemContextBuilder()
            .resourceResolverType(ResourceResolverType.JCR_MOCK)
            .afterSetUp(SETUP_CALLBACK)
            .build();
}

private static final AemContextCallback SETUP_CALLBACK = aemContext -> {

    // context path strategy
    MockCAConfig.contextPathStrategyRootTemplate(aemContext, Template.HOME_PAGE.getValue());

    // register sling models
    ...

    aemContext.registerInjectActivateService(new AutoClosableResourceResolverFactory());
    aemContext.registerInjectActivateService(new TitleService());

    createBlueprintPages(aemContext);

    TestInformation testInformation = TestInformation.getInstance();

    for (TestLiveCopyInformation info : testInformation.getLiveCopyInformationList()) {
        aemContext.load().json(info.getResourcePath(), info.getContentRoot() + "/" + info.getLanguage().getIsoCode());
    }

    // set default current page
    aemContext.currentPage(CONTENT_ROOT);

};

...

Правило в тесте:

@Rule
public final AemContext context = AppAemContext.getAemContext(RunMode.AUTHOR);

2 ответа

Решение

Благодаря @Jens я узнал, что ResourceResolver теперь реализует интерфейс AutoClosable (начиная с 6.2, мы используем 6.3.1.2), поэтому я мог удалить нашу собственную фабрику и использовать ResourceResolverFactory по умолчанию, теперь все работает нормально.

Вы должны позвонить buildTitleList или же Activate (новые соглашения о кодировании Java?), поскольку "аннотации декларативных сервисов OSGI" не используются в модульных тестах. У вас просто нет контейнера для вызова методов.

Другие вопросы по тегам