我想测试一个包含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实例化并正确连线?
答案 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。
希望它有所帮助。