用mock objects对taglib进行单元测试
因为JSP不是纯粹的java代码,所以,使用mock进行测试是行不通的,但是,taglib却是纯粹的java代码,可以测试,但是它也有麻烦的地方,我们要为抽象的java类的PageContext创建mocks。
在前面,我们曾学习了使用EasyMock和DynaMock的框架来创建mock,但是,他们使用的是Dynamic Proxy特性,他们只能为接口产生代理,不能用于类。这次,我们使用MockMaker。
安装插件的地址是http://mockmaker.org/ 安装的方法简单,Google!下面仅学习一下用法。
在要mock的类上右键,选择MockMaker—>select package 这样就在你选择的位置生成了mock程序。
现在让我们为DynaPropertiesTag类写一个mock测试程序。
package junitbook.pages; import junit.framework.TestCase; import org.apache.commons.beanutils.DynaBean; import org.apache.commons.beanutils.DynaProperty; import org.apache.commons.beanutils.BasicDynaClass; import javax.servlet.jsp.tagext.Tag; public class TestDynaPropertiesMO extends TestCase { private DynaPropertiesTag tag; private MockPageContext mockPageContext; private DynaBean createDynaBean() throws Exception { DynaProperty[] props = new DynaProperty[] { new DynaProperty("id", String.class), new DynaProperty("responsetime", Long.class) }; BasicDynaClass dynaClass = new BasicDynaClass("requesttime", null, props); DynaBean bean = dynaClass.newInstance(); bean.set("id", "12345"); bean.set("responsetime", new Long(500)); return bean; } protected void setUp() { tag = new DynaPropertiesTag(); mockPageContext = new MockPageContext(); tag.setPageContext(mockPageContext); } public void testDoStartTag() throws Exception { DynaBean bean = createDynaBean(); mockPageContext.setupFindAttribute(bean); mockPageContext.addExpectedFindAttributeValues("item"); mockPageContext.addExpectedSetAttributeStringObjectValues( "var", bean.getDynaClass().getDynaProperties()); tag.setItem("${item}"); tag.setVar("var"); int result = tag.doStartTag(); assertEquals(Tag.SKIP_BODY, result); } protected void tearDown() { mockPageContext.verify(); } }
和所有的mock objects一样,你需要仔细检查每一个将要被调用的mock objects方法,并告诉这些mocks如何的运转。在这个简单的例子中,只调用了一个
mock方法:PageContext.findAttribute().使用mock的第二个典型的步骤是告诉这些mock他们预定义接收的值。
何时使用mock,何时使用Cactus
一个较好的规则是尽量的把业务逻辑代码和集成代码分开。如果你为一个将从数据库中返回一个用户清单的标记编写代码,你应该用两个Java类来实现这个过程。第一个类处理商业逻辑,避免对Taglib API的依赖性。第二个类真正实现该标记。
“分离关注焦点”的策略是我们可以在多个环境中复用类并简化测试。你能用JUnit和mocks用一般的方法测试业务逻辑类。实现标记的集成代码可以用Cactus单独测试。
Cactus比mock所需的安装的东西多,但是物有所值。你可能不会经常的运行Cactus测试程序,但是他们保证了你的标记按你的要求在target环境中运行。
小结
Cactus通过侦听服务器端的JSP调用,提供了一种单元测试JSP的能力,这样就提供了在HTTP请求,HTTP会话,或在JSP上下文中创建对象的钩子。Cactus能对JSP进行单独的测试。而JspTestCase让我们能对taglib进行测试。
用MockMaker对taglib进行测试,从本章我们可见Cactus的强大之处!