我的JSF应用程序的接线测试用例有些问题。所以我想测试我的注销方法:
FacesContext context = EasyMock.createMock(FacesContext.class);
String userName = "testUserName";
HttpSession session = EasyMock.createMock(HttpSession.class);
ExternalContext ext = EasyMock.createMock(ExternalContext.class);
EasyMock.expect(ext.getSession(true)).andReturn(session);
EasyMock.expect(context.getExternalContext()).andReturn(ext).times(2);
context.getExternalContext().invalidateSession();
EasyMock.expectLastCall().once();
EasyMock.replay(context);
EasyMock.replay(ext);
EasyMock.replay(session);
loginForm = new LoginForm();
loginForm.setUserName(userName);
String expected = "login";
String actual = loginForm.logout();
context.release();
Assert.assertEquals(expected, actual);
EasyMock.verify(context);
EasyMock.verify(ext);
EasyMock.verify(session);
我的注销方法是:
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "/authentication/login.xhtml?faces-redirect=true";
}
我的问题是我在这里得到了一个nullpointer异常:EasyMock.expectLastCall()。once()它应该如何正确测试?我想这是嘲笑的东西,但我无法找到解决方案,我怎么能在这种情况下正确模拟FacesContext
为了完成上述工作,您可以使用PowerMock,这是一个允许您使用额外功能扩展EasyMock等模拟库的框架。在这种情况下,它允许您模拟FacesContext
的静态方法。
如果您使用的是Maven,请使用以下link检查所需的依赖项设置。
使用这两个注释注释您的JUnit测试类。第一个注释告诉JUnit使用PowerMockRunner
运行测试。第二个注释告诉PowerMock准备模拟FacesContext
类。
@RunWith(PowerMockRunner.class)
@PrepareForTest({ FacesContext.class })
public class LoginFormTest {
现在继续使用PowerMock模拟FacesContext
,就像你为其他类做的那样。唯一不同的是,这次你在课堂上执行replay()
和verify()
而不是实例。
@Test
public void testLogout() {
// mock all static methods of FacesContext
PowerMock.mockStatic(FacesContext.class);
FacesContext context = EasyMock.createMock(FacesContext.class);
ExternalContext ext = EasyMock.createMock(ExternalContext.class);
EasyMock.expect(FacesContext.getCurrentInstance()).andReturn(context);
EasyMock.expect(context.getExternalContext()).andReturn(ext);
ext.invalidateSession();
// expect the call to the invalidateSession() method
EasyMock.expectLastCall();
context.release();
// replay the class (not the instance)
PowerMock.replay(FacesContext.class);
EasyMock.replay(context);
EasyMock.replay(ext);
String userName = "testUserName";
LoginForm loginForm = new LoginForm();
loginForm.setUserName(userName);
String expected = "/authentication/login.xhtml?faces-redirect=true";
String actual = loginForm.logout();
context.release();
Assert.assertEquals(expected, actual);
// verify the class (not the instance)
PowerMock.verify(FacesContext.class);
EasyMock.verify(context);
EasyMock.verify(ext);
}
我创建了一个blog post,它更详细地解释了上面的代码示例。
这个:
FacesContext context = EasyMock.createMock(FacesContext.class);
不会更改此返回值(在被测试的类中):
FacesContext.getCurrentInstance()
您需要扩展FacesContext
然后使用模拟的FacesContext调用受保护的方法setCurrentInstance
。