我对抽象类BuildSupport很好奇:怎么可以做这么多神奇的事情呢?比如SwingBuilder和AntBuilder。
因此我写了如下一个Groovy测试来刨析一下其行为:
package groovy.util class SpoofBuilder extends BuilderSupport{ def log = [] protected void setParent(Object parent, Object child){ log << "sp" log << parent log << child } protected Object createNode(Object name){ log << 'cn1' log << name return 'x' } protected Object createNode(Object name, Object value){ log << 'cn2' log << name log << value return 'x' } protected Object createNode(Object name, Map attributes){ log << 'cn3' log << name attributes.each{entry -> log << entry.key; log << entry.value} return 'x' } protected Object createNode(Object name, Map attributes, Object value){ log << 'cn4' log << name attributes.each{entry -> log << entry.key; log << entry.value} log << value return 'x' } protected void nodeCompleted(Object parent, Object node) { log << 'nc' log << parent log << node } } // simple node def b = new SpoofBuilder() assert b.log == [] def node = b.foo() assert b.log == ['cn1','foo','nc',null, node] // simple node with value def b = new SpoofBuilder() def node = b.foo('value') assert b.log == ['cn2','foo','value', 'nc',null,node] // simple node with one attribute def b = new SpoofBuilder() def node = b.foo(name:'value') assert b.log == [ 'cn3','foo', 'name','value', 'nc',null,'x'] // how is closure applied? def b = new SpoofBuilder() b.foo(){ b.bar() } assert b.log == [ 'cn1','foo', 'cn1','bar', 'sp', 'x', 'x', 'nc','x','x', 'nc',null,'x']
SpoofBuilder只是一个简单的BuilderSupport实例,除了记录被调用的日志和每个节点(node)返回'x'以为,什么事情都没有做。
测试的部分采用不同方式来调用SpoofBuilder,其日志揭示了在”Build”过程中那些方法被调用。 此测试同时也验证了我假想的builder模式的工作方式,在此基础上,我又写了一个用于Canoo WebTest的AntBuilder。
. “MacroStepBuilder”允许在Groovy代码中使用Canoo WebTest “steps” (为了测试遍历一个webapp),因此Groovy现在已经是Canoo WebTest 社区的一等公民了。
在编写以上的测试过程中,我也磕磕碰碰了一些事情,这是其中的两点:
而我很欣赏的两点是: