如何模拟 JSF class UIViewRoot

How to mock the JSF class UIViewRoot

我正在测试我的 JSF 应用程序 (v2.2.14),但我遇到了一些困难,因为我无法模拟 UIViewRoot class。 当我尝试用 Mockito 模拟这个 class 时,我收到错误

java.lang.ExceptionInInitializerError 
...
...
caused by java.util.MissingResourceException: Can't find javax.faces.LogStrings bundle

我使用 viewRoot 来管理应用程序的 java.util.Locale,有时我需要阅读这些信息。

我可以通过哪种方式模拟此 class 以继续我的测试用例?

谢谢!

目前我已经将依赖于 JSF 的所有代码包装在一个 class 中,现在我可以轻松地模拟它了。

@Component
public class FacesComponent implements Serializable {

    public Locale getLocaleFromFrontend() {
        return FacesContext.getCurrentInstance().getViewRoot().getLocale();
    }
}

然后我的测试class与此类似

    @Autowired
    @InjectMocks
    private LocalDateConverter localDateConverter;

    @Autowired
    @Spy
    private FacesComponent facesComponent;
...
...
MockitoAnnotations.initMocks(this);
Mockito.doReturn(null).when(facesComponent).getLocaleFromFrontend();

如果您使用 PowerMockito,您可以使用 @SuppressStaticInitializationFor 注释来删除静态初始化程序。 https://github.com/powermock/powermock/wiki/SuppressUnwantedBehavior

例如,如果代码是:

import java.util.Locale;
import javax.faces.context.FacesContext;

public class TestedClass
{

  public Locale getLocale()
  {
    return FacesContext.getCurrentInstance().getViewRoot().getLocale();
  }
}

以下测试将通过(JavaEE7,PowerMockito 1.6.4):

    @RunWith(PowerMockRunner.class)
    @SuppressStaticInitializationFor({"javax.faces.component.UIViewRoot", "javax.faces.component.UIComponent", "javax.faces.component.UIComponentBase"})
    @PrepareForTest({TestedClass.class, FacesContext.class, UIViewRoot.class, UIComponentBase.class, UIComponent.class, Locale.class})
    public class TestedClassTest {

        private final FacesContext facesContext = Mockito.mock(FacesContext.class);
        private final UIViewRoot uiViewRoot = Mockito.mock(UIViewRoot.class);
        private final Locale locale = PowerMockito.mock(Locale.class);

    private final TestedClass instance = new TestedClass();

    @Before
    public void setUp() {
        PowerMockito.mockStatic(FacesContext.class);

    Mockito.when(FacesContext.getCurrentInstance()).thenReturn(facesContext);

        Mockito.when(facesContext.getViewRoot()).thenReturn(uiViewRoot);
      Mockito.when(uiViewRoot.getLocale()).thenReturn(locale);
    }

    /**
     * Test of getLocale method, of class TestedClass.
     */
    @Test
    public void testGetLocale() {

        assertEquals(locale, instance.getLocale());
    }
}

确保同时抑制 UIViewRoot 的超级 类。