我有一个动态AORule类,它有一个嵌入式DyanmicRule类实例作为这样的委托,AORule上的方法调用规则上的一个动作,在调用它之前测试是否设置了dynamicExecution闭包
@Component
@Scope("prototype")
@ActiveObject
@Slf4j
@EqualsAndHashCode
class AORule implements org.easyrules.api.Rule {
//setup delegate dynamicRule and make it a part of this ActiveObject
@Delegate DynamicRule rule
AORule (name, description=null) {
rule = new DynamicRule (name, description ?: "Basic Active Object Rule")
}
AORule () {
rule = new DynamicRule ()
}
....rest of class with a method like this
@ActiveMethod
void active_execute () {
//rule.execute()
if (rule.dynamicExecution != null) {
log.debug "activeExec : running dynamicExecution closure "
rule.dynamicExecute() //should call closure, where this is defined
}
else {
log.debug "activeExec : running std Execution action "
rule.execute()
}
} ....
其中DynamicRule类的顶部如下所示
@InheritConstructors
@Component
@Slf4j //use Groovy AST to get logger
@EqualsAndHashCode
class DynamicRule extends BasicRule implements org.easyrules.api.Rule {
Closure dynamicEvaluation = null
Closure dynamicExecution = null
....
然后我尝试为此定义一个简单的spock测试,并像这样Stub the DynamicRule
def "set execution closure directly when doing an execute action " () {
given:"setup of stub for testing "
def mockres
def stub = new StubFor (DynamicRule)
stub.demand.dynamicExecute { mockres = "did nothing" }
stub.demand.getDynamicExecution = {true} // pretend this has been set
when : "execution passing closure value at same time "
//have to run new, actions etc in scope of class stub
stub.use {
def rule = new AORule ()
rule.execute()
}
then : "test execute closure ran as expected "
mockres == "did nothing"
}
在此测试中 - 尝试设置Stub需求getDynamicExecution
属性(闭包)以返回true,另一个要求将方法dynamicExecution设置为def mockres
结果。然后我声称它有一些价值
然而这给我一个这样的错误。
groovy.lang.MissingPropertyException: No such property: getDynamicExecution for class: groovy.mock.interceptor.Demand
at org.easyrules.spring.AORuleSpecTest.set execution closure directly when doing an execute action (AORuleSpecTest.groovy:91)
如何在类中设置模拟属性访问的预期结果。我认为设置getPropertyName = {some value}
的Stub需求预期就可以了。我做错了什么?
PostScript:
我试图设置一个像我这样使用的测试方法的笨拙版本
class DummyStubSpecTest extends Specification {
def "test z stub " () {
def res
given :
def zstub = new StubFor (Zthing.class)
zstub.demand.execute {res = "hello"}
zstub.demand.getVar {false}
when :
zstub.use {
def a = new Athing()
a.z.execute()
}
then :
res == "hello"
}
def "test Athing stub " () {
def res
given :
def astub = new StubFor (Athing.class)
astub.demand.doit {res = "hello"}
when :
astub.use {
def a = new Athing ()
a.doit()
}
then :
res == "hello"
}
}
和这样的spock测试
def "test z stub " () {
def res
given :
def zstub = new StubFor (Zthing.class)
zstub.demand.execute {res = "hello"}
zstub.demand.getVar {false}
when :
zstub.use {
def a = new Athing()
a.z.execute()
}
then :
res == "hello"
}
这确实有效 - 所以我不确定我在前面的例子中做错了什么
第二篇后记:傍晚2月3日
建议我应该使用GroovyMock运行测试,所以我尝试了这个
def "set execution closure using GroovyMock to Stub to execute action " () {
given:"setup of stub for testing "
def mockres
GroovyMock (DynamicRule, global:true)
DynamicRule.dynamicExecute() >> {mockres = "did nothing"}
when : "execution passing closure value at same time "
//have to run new, actions etc in scope of class stub
def rule = new AORule ()
rule.execute()
then : "test execute closure ran as expected "
mockres == "did nothing"
}
但是当我运行它时,断言再次失败 - 当execute()触发我的模拟对象上的内部DynamicRule.dynamicExecute()方法时,没有设置mockres。
第三篇文章:3月3日上午
今天早上我再次尝试过 - 首先是一对假的类和虚拟测试来尝试groovyMocks - 这是有效的。这是我的同名Athing and Zthing
//define subject under test
class Athing {
def z = new Zthing()
def res
def doit() {
z.greet()
res = z.execute()
}
}
//dependency to be stubbed
class Zthing {
def var = true
def execute() {if (var) println "its true" else println "its false"; var}
def greet() { println "hello"}
}
这是我定义的测试
class DummyStubSpecTest extends Specification {
def "test z with GroovyMock " () {
given:
def a = new Athing()
def res
def mock = GroovyMock (Zthing) { //, global:true
1*execute() >> {println "stub called"; res=true}
}
a.z = mock
when:
a.doit()
then:
res == true
}
我创建了模拟并设置了交互期望(1 *)和存根响应,它将我的外部res
设置为某个字符串,以便我可以测试它。
因为' a'有一个嵌入式的''例如,我覆盖a.z
引用以指向模拟。然后我在when子句中调用SUT,并检查是否已设置res
。这确实有效
class AORule implements org.easyrules.api.Rule {
//setup delegate dynamicRule and make it a part of this ActiveObject
@Delegate DynamicRule rule
AORule (name, description=null) {
rule = new DynamicRule (name, description ?: "Basic Active Object Rule")
}
AORule () {
rule = new DynamicRule ()
} ....
其中AORule中的execute方法如下所示
void execute () {
active_execute()
}
/**
* Active method manages async action through object inside through hidden actor.
* variable 'rule' is the variable we are protecting. Runs either any dynmicExecution closure
* where defined or just runs the standard class execute method
*
* @return void
*/
@ActiveMethod
void active_execute () {
//rule.execute()
if (rule.dynamicExecution != null) {
log.debug "activeExec : running dynamicExecution closure "
rule.dynamicExecute() //should call closure, where this is defined
}
else {
log.debug "activeExec : running std Execution action "
rule.execute()
}
} ....
我对此的测试看起来像这样 def"使用GroovyMock设置执行闭包来去除动态执行动作" (){
given:"setup of stub for testing "
def mockres
def mock = GroovyMock (DynamicRule) { //, global:true
1*dynamicExecute() >> {-> println "stub called"; mockres = "did nothing" }
0*execute()
}
aorule.rule = mock
when : "execution passing closure value at same time "
//have to run new, actions etc in scope of class stub
//def rule = new AORule ()
aorule.setDynamicExecution {println "hi"}
aorule.execute()
then : "test execute closure ran as expected "
mockres == "did nothing"
}
测试无法正常工作 - 断言显示mockres
为空(未设置)
我认为这可能是因为activeEvaluate在内部检查activeEvaluation是否已设置闭包,所以我尝试将GroovyMock更改为GroovySpy(以便我的aorule.setDynamicExecution
调用可以正常工作),并且它仍然失败
我很困扰,我似乎无法看到我要去哪里。我的简单愚蠢的屁股示例似乎有效 - 我真正的考验并不是 - 我做错了什么...... aaahg,
我也尝试过暴力破解并使用metaClass来破解执行闭包来设置mockres,并且也没有被调用 - 我被卡住了