在JSF 2.2应用程序中,我想构建一个war文件,用于使用Selenium进行测试。在那个webtest.war中,我想用一个名为WebtestNodeCache的模拟版本替换一个名为NodeCache的中心类,以保持数据库和其他外部依赖关系不被测试。
NodeCache是托管bean:
@javax.faces.bean.ManagedBean(name = NodeCache.INSTANCE)
@javax.faces.bean.ApplicationScoped
public class NodeCache {
public static final String INSTANE = "nodecache";
// ...
}
为了潜入WebtestNodeCache,我使用这样的ServletContextListener:
public class WebtestContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
WebtestNodeCache nodeCache = new WebtestNodeCache();
ServletContext context = event.getServletContext();
context.setAttribute(NodeCache.INSTANCE, nodeCache);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {}
}
在正常版本中,WebtestContextListener和WebtestNodeCache从war文件中排除,在测试版本中,它们都包含在内。
这似乎有效:当我登录时,我从WebtestNodeCache获取虚拟节点。
这是在应用程序上下文中替换bean的可靠方法,还是我很幸运?
有没有更好的方法潜入测试假人?
答案 0 :(得分:0)
同时使用@ManagedBean
注释和侦听器替换对象不起作用。代码总是使用unmocked生产代码托管bean。
定义具有相同名称的新@ManagedBean
是一个错误,并阻止部署。
我最终得到了这个:
在真实bean及其模拟器上放置@ManagedBean
注释名称相同。
构建时,只在构建webtest.war时包含模拟,但不包括常规构建中的模拟。
构建时,使用构建脚本(在我的情况下为Gradle)复制并过滤源,在生产代码中查找@ManagedBean
声明后面的特殊注释,并取出这些行以删除关于生产代码的@ManagedBean
声明,以便只保留模拟中的那些。
所以原来的NodeCache现在看起来像这样:
@javax.faces.bean.ManagedBean(name = NodeCache.INSTANCE) // webtest:remove
@javax.faces.bean.ApplicationScoped // webtest:remove
public class NodeCache {
public static final String INSTANE = "nodecache";
// ...
}
并且模拟版本具有相同的注释,只是没有注释:
@javax.faces.bean.ManagedBean(name = NodeCache.INSTANCE)
@javax.faces.bean.ApplicationScoped
public class WebtestNodeCache extends NodeCache {
// ...
}
以下是Gradle构建脚本的相关部分:
boolean isWebtest = false
gradle.taskGraph.whenReady { taskGraph ->
isWebtest = taskGraph.hasTask(compileWebtestWarJava);
}
task copySrc(type: Copy) {
from "src"
into "${buildDir}/src"
outputs.upToDateWhen {
// Always execute this task so that resources do or don't get filtered
// when switching between normal war file and webtests.
false
}
filter { String line ->
isWebtest && line.contains("webtest:remove") ? null : line;
}
}
这解决了我的问题。希望别人觉得它很有用。