如何在Grails Spock单元测试中初始化/连接bean?

时间:2014-11-18 12:46:39

标签: spring grails spring-data spock

我想测试一个包含bean的Grails控制器(当我开始工作时,我会将它移动到服务中,但我现在只想保持简单。)

//resources.groovy
beans {
    myBean(com.me.MyBean) 
}


// MyBean.java
// this needs to be in java as it is playing with spring-data-neo4j
package com.me;
public class MyBean {
    String show() {
        return "Hello";
    }
}

// TestController.groovy
package com.me

import com.me.MyBean

class TestController {

    def myBean

    def index() {
        render myBean.show()
    }
}


// TestControllerSpec.groovy
package com.me

import grails.test.mixin.TestFor
import spock.lang.Specification

import com.me.*

@TestFor(TestController)
class TestControllerSpec extends Specification {

    def myBean

    def setup() {
        defineBeans {
            myBean(com.me.MyBean) {bean->
                bean.autowire = true
            }
        }
    }

    def cleanup() {
    }

    def "show() returns Hello"() {
        when:
        def rc = controller.myBean.show()
        def rc2 = myBean.show()

        then:
        rc == "Hello"
        rc2 == "Hello"
    }
}

在TestControllerSpec中,myBean为null。 controller.myBean也为null。我认为这是因为Spring没有选择bean并将其连接起来。我在单元测试中收集到的并不是所有的spring bean都可用,但是我需要做些什么才能使controller.myBean实例化并正确连线?

1 个答案:

答案 0 :(得分:3)

你必须嘲笑myBean,如下所示

def myBean = Mock(MyBean)

MyBean myBean = Mock()

然后根据需要存根方法,如下所示:

myBean.show >> "test data"

然后将其分配给已经为您模拟过的控制器对象。

controller.myBean = myBean

然后你去。

或者可选地,您可以存根myBean并提供存根实现。例如,

MyBean myBean = Stub(){
show() >> {return "sample text"}
}
controller.myBean = myBean

这样做的原因是我们没有测试应用程序实体(如控制器,视图或域)的集成,但我们正在测试单个单元即方法,因此我们应该只测试它并进行集成我们应该使用集成除了在正常情况下不需要任何模拟之外,测试用例在所有内容中都相似。

修改

发现了使用defineBeans闭包模拟服务或bean的另一个有用功能,如下所示:

        defineBeans {
            adapter(Adapter)
            helperService(HelperService)
        }

这将允许从grailsApplication访问bean。

希望它有所帮助。