当我尝试设置属性值

时间:2016-03-02 16:19:53

标签: groovy spock stubbing

我有一个动态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。这确实有效

然而,我真正的班级/考试仍拒绝和我一起打球。所以我的AORule有一个DynamicRule引用

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,并且也没有被调用 - 我被卡住了

0 个答案:

没有答案