Как я могу издеваться над JSF FacesContext с ViewMap для модульных тестов вне реального веб-приложения? - PullRequest
3 голосов
/ 07 сентября 2011

РЕДАКТИРОВАТЬ: Исправлен вопрос для удобства чтения. Пожалуйста, игнорируйте комментарии до 31 октября.

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

Теперь, начиная с интеграционного тестирования, мы хотим иметь возможность модульного тестирования каждой части и, таким образом, нуждаемся в способе макета полного контекста Faces (для доступа через обертку) для тестирования классов, которые его используют.

Важной частью здесь является complete , означающее, что он должен иметь инициализированный ViewMap, поскольку именно здесь наш ViewScope помещает свои объекты.


Я пробовал разные подходы:

1) сланцевый тест : Я продвинулся дальше всего, но, к сожалению, проект закрыт.

Пока что я обернул FacesContext в провайдере, который позволяет мне заменить его на Mocked FacesContext для тестирования. Я также модифицировал сланцевую реализацию AbstractViewControllerTestCase для включения контекста приложения.

Однако при вызове MockedFacesContext.getViewRoot().getViewMap(), поскольку это вызовет UnsupportedOperationException. Причины, по-видимому, заключаются в том, что MockApplication не создает экземпляр Application.defaultApplication (он нулевой), который требуется для вызова этого метода. Кажется, это ограничение сланцевого теста.


2) JMock или mockito Мне кажется, что они вообще ничего не высмеивают, так как большинство участников просто останутся нулевыми. Не знаю, могут ли JMock или mockito действительно вызывать методы инициализации propper.


3) Пользовательский Faces Mocker: Мне кажется, это единственный оставшийся вариант, но у нас нет времени проанализировать, как инициализируются Faces, и воссоздать поведение для насмешливых целей. Может быть, кто-то раньше этого не делал и может поделиться основными путевыми точками и хитами?


Или есть какой-нибудь альтернативный способ насмешки над FacesContext вне веб-приложения?

1 Ответ

4 голосов
/ 30 ноября 2011

Я бы пошел с PowerMock + Mockito:

По вашей ссылке:

private Map<String,Object> getViewMap() {
    return FacesContext.getCurrentInstance().getViewRoot().getViewMap();
}

В тесте:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ FacesContext.class });
public class TheTest {
    /*
     * fake viewMap.
     */
    private Map<String,Object> viewMap = Maps.newHashMap() // guava

    /**
     * mock for FaceContext
     */
    @Mock
    private FacesContext faceContext;

    /**
     * mock for UIViewRoot
     */
    @Mock
    private UIViewRoot uiViewRoot;

    @Before
    public void setUp() {
        Mockito.doReturn(this.uiViewRoot).when(this.faceContext).getViewRoot();
        Mockito.doReturn(this.viewMap).when(this.uiViewRoot).getViewMap();

        PowerMock.mockStatic(FacesContext.class);
        PowerMock.doReturn(this.faceContext).when(FacesContext.class, "getCurrentInstance");
    }

    @Test
    public void someTest() {
        /*
         * do your thing and when  
         * FacesContext.getCurrentInstance().getViewRoot().getViewMap(); 
         * is called, this.viewMap is returned.
         */
    }
}

Некоторые читают:

...