如何在实际Web应用程序之外使用ViewMap模拟JSF FacesContext进行单元测试?

时间:2011-09-07 13:42:39

标签: jsf junit mocking facescontext

编辑:清除问题的可读性。请忽略截至10月31日的评论。

在我们的应用程序堆栈中,我们使用许多较小的jar模块,这些模块将组合到最终的Web应用程序中。一个模块定义了JSF功能,比如实现this ViewScope。

现在从集成测试开始,我们希望能够对每个部分进行单元测试,因此需要一种方法来模拟完整的Faces Context(通过包装器访问)来测试使用它的类。

这里的重要部分是完整,这意味着它必须有一个初始化ViewMap,因为这是我们的ViewScope放置其对象的地方。


我尝试过不同的方法:

1)页岩测试:我已经走得最远,但不幸的是项目已经退役了。

到目前为止,我已将FacesContext包装在Provider中,允许我将其替换为Mocked FacesContext进行测试。我还修改了AbstractViewControllerTestCase的shale实现以包含应用程序上下文。

然而,在调用MockedFacesContext.getViewRoot().getViewMap()时会抛出UnsupportedOperationException。原因似乎是MockApplication没有实例化此方法调用所需的Application.defaultApplication(它为null)。这似乎是页岩测试的限制。


2)JMock或mockito 在我看来,不要真的嘲笑任何东西,因为大多数成员都会保持为空。不知道JMock或mockito是否可以实际调用propper初始化方法。


3)自定义面孔Mocker:对我而言,这似乎是唯一剩下的选项,但我们没有时间分析Faces的初始化方式,并为模拟目的重新创建行为。也许有人之前没有这个,可以分享主要的航点和陷阱吗?


或者有没有其他方法可以在Web应用程序之外模拟FacesContext?

1 个答案:

答案 0 :(得分:4)

我会选择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.
         */
    }
}

一些阅读: