Как смоделировать объект страницы CQ5, содержащий тег cq5

У меня есть метод, на котором я хотел бы запустить тест JUnit. Я издеваюсь над страницей cq5, используя JMockit.

Мой метод тестирования выглядит так

@Mocked
Page page;
@Mocked
PageManager pageManager;
Tag testTag = pageManager.createTag("someID","someTitle","someDescription");//i've left out the try catch for brevety
System.out.println(testTag.getTitle()); // always null here


public void testSomeMethod() {

    new Expectations() {
        // variables declared here are mocked by default
        {
            page.getProperties();
            propertyMap.put("cq:tags", testTag);
            returns(new ValueMapDecorator(propertyMap));
        }
    };
    String propertyValue = methodToBeTested(page);
    Assert.assertEquals(propertyValue, "someTitle");
}

И фактический тестируемый метод делает это: -

public static String getTopic(Page page) {

    String topic = null;
    Tag[] tags = page.getTags();
    System.out.println(tags.size()); // returns 0 when I run the test.
    for (int i = 0; i < tags.length; i++) {
        Tag tag = tags[i];

            topic = tag.getTitle();
        }
    }
    return topic;

}

Это всегда возвращает null, когда я запускаю тест; однако тестируемый метод работает корректно в реальном сценарии.

Я подозреваю, что неправильно устанавливаю/издеваюсь над PageManager, и, следовательно, мой testTag равен null

Как мне правильно издеваться над этим, чтобы получить результат, который я ищу?


person bongman1612    schedule 07.05.2015    source источник
comment
Тестируемый метод вызывает page.getTags(), но для него не зафиксировано ожидание; вместо этого тест записывает page.getProperties(), который никогда не вызывается из метода getTopic(Page); поэтому он возвращает null, т. е. тест не согласуется с тем, что делает тестируемый метод.   -  person Rogério    schedule 09.05.2015
comment
Вы также можете попробовать использовать тестирование wcm.io. Я знаю, что это позволяет вам загружать файлы JSON и использовать их в качестве содержимого для имитации экземпляров AEM Page. Я не пробовал это с тегами, хотя.   -  person toniedzwiedz    schedule 11.06.2015
comment
см. мой ответ здесь: forums.adobe.com/thread/2536290 о том, почему вы становитесь пустым массив для Page#getTags   -  person Ahmed Musallam    schedule 04.02.2019


Ответы (3)


Вы подходите к этому тестированию не с той стороны. То, как работают моки (обычно - я никогда не работал конкретно с jmockit), заключается в том, что вы создаете пустой объект, который действует как самозванец. Этот самозванец не является настоящим менеджером страниц - он только действует как таковой и представляет себя таковым всякий раз, когда его спрашивают. Когда кто-то просит этого самозванца что-то сделать (например, вызвать его метод), самозванец не знает, что делать, поэтому ничего не делает и возвращает null. Однако вы можете указать самозванцу, как вести себя в тех или иных ситуациях. А именно, вы можете указать ему, что делать при вызове метода.

В вашем случае вам не нужно создавать фактические теги для проверки этого метода - вам нужно только издеваться над объектом страницы, который при запросе его тегов вернет массив, содержащий издевательский тег, который, в свою очередь, при запросе это название, ответит на название, которое вы действительно хотите использовать в своем тесте.

Я не знаю jmockit, поэтому не могу предоставить фрагмент кода. Однако это общий вопрос, не связанный строго с CQ5/AEM.

person CptBartender    schedule 07.05.2015

Возможно, вы не сможете найти какие-либо методы «установщика» для всех объектов, которые вы пытаетесь имитировать, и в любом случае это неправильный подход к имитированию.

Как уже упоминалось, лучший способ - использовать издевательские страницы. Вы можете использовать класс Expectations (mockit.Expectations), чтобы имитировать значения, которые должны быть возвращены определенными методами в объекте.

См. этот пример издевательства над объектом SlingHttpServletRequest в классе MockedClass.

@Test
    public void testMethod(@Mocked final SlingHttpServletRequest request){
        String indicator ;
        new Expectations() {
            {
                request.getParameter("archive");
                returns("true");
            }
        };

        indicator = OriginalClass.originalMethod(request);
        Assert.assertEquals(indicator, "true");
    }

Аналогичным образом вы можете издеваться над другими объектами и их желаемыми значениями.

person Riju Mahna    schedule 07.05.2015

Я ответил на тот же вопрос здесь: https://forums.adobe.com/thread/2536290

Я столкнулся с той же проблемой. чтобы разрешать теги, они должны существовать под /content/cq:tags/your/tag или /etc/tags (устаревшие).

Реализация Page#getTags вызывает TagManager#getTags, который, в свою очередь, пытается разрешить фактический ресурс тега в репозитории. Поскольку вы тестируете в контексте AEM, вам необходимо загрузить эти теги в соответствующее место, чтобы MockTagManager мог их разрешить.

Это означает, что вам нужно загрузить свои теги в тестовый контекст AEM точно так же, как вы загрузили свои ресурсы (через json).

Взгляните на реализацию aem-mock TagManager здесь: wcm-io-testing/MockTagManager.java при разработке · wcm-io/wcm-io-testing · GitHub начните с метода resolve и отладьте свой путь, чтобы выяснить, где вам нужно чтобы добавить эти теги.

person Ahmed Musallam    schedule 04.02.2019