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" не используются в модульных тестах. У вас просто нет контейнера для вызова методов.