我正在努力在我的JSF支持bean类上实现单元测试...例如,一些方法使用会话或请求参数,使用这种代码获得:
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("paramKey");
.
我的问题是:如何测试从会话或请求中获取值的方法?
我通常做的是避免将静态方法调用到我想测试的bean中.这意味着您当前的代码将被重构:
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().get("paramKey");
Run Code Online (Sandbox Code Playgroud)
有没有办法用静态方法调用来测试它们?可能有,但他们给我带来了很多麻烦而不是帮助.所以最后我摆脱了它们并改变了我的设计.让第二个豆做它(你稍后会嘲笑).在您的情况下,创建一个@SessionScoped
管理该功能的bean:
@ManagedBean
@SessionScoped
public class SessionBean{
public Object getSessionParam(String paramKey){
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().get(paramKey);
}
}
Run Code Online (Sandbox Code Playgroud)
并在需要它的每个bean中注入该bean(我通常从拥有它的抽象bean扩展我的视图/请求bean,因此不必在每个bean中实现它):
@ManagedBean
@RequestScoped
public class RequestBean{
@ManagedProperty(value="#{sessionBean}")
private SessionBean sessionBean;
public void accessSessionParam(){
sessionBean.getSessionParam("name");
}
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以通过辅助设备轻松访问静态方法SessionBean
.那么,如何测试呢?只需创建一个模拟(例如使用Mockito):
public class Test{
public void test1(){
SessionBean sb = Mockito.mock(SessionBean.class);
//Mock your 'getSessionParam' method
ValueBean vb = new ValueBean();
Mockito.when(sb.getSessionParam(Mockito.anyString()).thenReturn(vb);
//Create your bean to test and set your mock to it
RequestBean rb = new RequestBean();
rb.setSessionBean(sb);
//here you can test your RequestBean assuming
//sessionBean.getSessionParam()
//will return vb for every single call
}
}
Run Code Online (Sandbox Code Playgroud)
这是可能的嘲笑FacesContext
,但这是不够理想.Mockito示例:
import javax.faces.context.FacesContext;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
public abstract class ContextMocker extends FacesContext {
private ContextMocker() {}
private static final Release RELEASE = new Release();
private static class Release implements Answer<Void> {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
setCurrentInstance(null);
return null;
}
}
public static FacesContext mockFacesContext() {
FacesContext context = Mockito.mock(FacesContext.class);
setCurrentInstance(context);
Mockito.doAnswer(RELEASE)
.when(context)
.release();
return context;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的平台支持它,则更喜欢CDI到JSF托管bean.CDI具有静态依赖性检查并注入代理以防止范围泄漏.CDI不支持JSF的所有功能,但在必要时将JSF托管bean连接到CDI相对容易.
JSF托管bean限制了您将类型注入的范围,但即使这样也会导致范围泄漏.例如,#{sessionScope}
即使对象属于请求作用域,也可以将变量注入会话作用域bean ExternalContext
.可以通过编写自己的JSF bean代理来克服这个问题.
注意:大部分内容都是用Java EE 6编写的; Java EE 7可能会改进一些东西.
归档时间: |
|
查看次数: |
7608 次 |
最近记录: |