jUnit: NPE при инициализации частного участника - PullRequest
0 голосов
/ 01 декабря 2011

Иметь jUnit тест, который инициализирует мой бин:

ShowProducts sp = new ShowProducts();

получил NullPointerException в следующей строке в ShowProducts.java:

    private Locale locale = FacesContext.getCurrentInstance().getViewRoot()
                .getLocale();

...
    public Locale getLocale() {
        return locale;
    }

    public String getLanguage() {
        return locale.getLanguage();
    }

    public void localize() {
        String localeParam = FacesContext.getCurrentInstance()
                .getExternalContext().getRequestParameterMap().get("lang");
        locale = new Locale(localeParam);
        FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    }

Как правильно инициализировать это поле в тесте?

EDIT:

лица-конфигурации:

<application>
    <locale-config>
        <default-locale>ru</default-locale>
        <supported-locale>ua</supported-locale>
    </locale-config>
    <resource-bundle>
        <base-name>msg</base-name>
        <var>m</var>
    </resource-bundle>
</application>

.xhtml:

    <h:form>
        <h:commandLink action="#{showProducts.localize}" includeViewParams="true"
                       rendered="#{showProducts.language=='ua'}">
            #{m.rus}.
            <f:param name="lang" value="ru"/>
        </h:commandLink>
        <h:commandLink action="#{showProducts.localize}" includeViewParams="true"
                       rendered="#{showProducts.language=='ru'}">
            #{m.ukr}.
            <f:param name="lang" value="ua"/>
        </h:commandLink>
    </h:form>

Ответы [ 2 ]

3 голосов
/ 01 декабря 2011

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

В вашем тестовом примере вы хотите убедиться, что: - ShowProducts извлекает надлежащий языковой стандарт из контекста граней / корня представления - выполняет другие действия правильно.

Я рекомендую вам использовать jmockit.Ваш тестовый пример будет выглядеть примерно так:

 @Test
 public void testShowProducts(@Cascading final FacesContext facesContext) {
        final Locale locale = new Locale(...)
        new Expectations() {
           {
              FacesContext.FacesContext.getCurrentInstance().getViewRoot().getLocale();
              returns(locale);
           }


        };
       ShowProducts sp = new ShowProducts();

       ...  do your assertions other stuff there
 }

Этот метод применим ко многим контекстам и значительно упрощает тестовый код.

1 голос
/ 01 декабря 2011

Доступ к статическим методам затрудняет написание тестов.

Либо передайте Locale с помощью конструктора, либо используйте установщик.

Самое простое изменение - добавить второй конструктор с параметром Locale в качестве параметра и использовать его для юнит-теста. Затем конструктор по умолчанию инициализирует поле из FacesContext.

Для более чистого дизайна вы должны извлечь Localizer, где вы обрабатываете всю локализацию, чтобы затем отделить ShowProducts, который не нуждается в FacesContext от Localizer, который делает.

Локализатор будет выглядеть примерно так:

public class Localizer {
    public void localize() {
        String localeParam = FacesContext.getCurrentInstance()
                .getExternalContext().getRequestParameterMap().get("lang");
        locale = new Locale(localeParam);
        FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    }
}

Это не имеет ничего общего с ShowProducts. Не уверен, что вам нужно getLanguge().

...