我有一个示例域名,例如
class User {
String username
String password
def userHelper
static contraints = {
username(nullable: false, blank: false)
password nullable: false, blank: false, validator: {pwd, userInstance ->
return userInstance.userHelper.validatePassword(pwd)
}
}
}
我userHelper
resources.groovy
正在注入beans = {
userHelper(UserHelper)
}
Cannot invoke method validatePassword() on null object
当我从浏览器测试我的应用程序时,一切运行正常。但是,我在尝试为此编写功能测试时遇到异常。
错误说明:userHelper
所以我假设在运行我的功能测试用例时没有设置 @TestFor(UserController)
@Mock([User])
class UserControllerSpecification extends Specification {
def "save user" () {
given:
request.contentType = "application/json"
request.JSON = """
{user:
{
username: "somtething"
password: "something"
}
}
"""
when:
controller.save()
then:
User.count() == 1
}
}
。
我的测试用例如下:
class UserController {
def userService
def save() {
def user = new User(params?.user)
request.withFormat {
json {
if(user.validate())
userService.processUser()
//do something
else
//do something else
}
}
}
}
更新
控制器:
userHelper
问题
User
域上设置Bootstrap.groovy
属性?答案 0 :(得分:4)
您是否尝试过使用defineBeans
?由于这是一个单元测试,因此您必须明确定义bean。这通常是在JUnit中完成的
defineBeans{
userHelper(UserHelper){bean ->
//in case you have other beans defined inside helper
bean.autowire = true
}
}
您可以在设置方法中defineBeans
使其适用于所有测试用例。
@Before
void setup(){
defineBeans{
userHelper(UserHelper){bean ->
//in case you have other beans defined inside helper
bean.autowire = true
}
}
}
更新:
似乎在spock的情况下你可以直接在单元测试中注入一个spring bean(测试扩展Specification
)
class UserControllerSpecification extends Specification {
def userHelper //injected here in case of spock
def "save user" () {
................
}
}
答案 1 :(得分:1)
尝试使用metaClass。
def setup(){
User.metaClass.getUserHelper = {new UserHelper()}
}
如果这是你想要的,你也可以模拟userHelper。
def setup(){
def userHelperMock = Mock(UserHelper)
userHelperMock.validatePassword(_) >> true
User.metaClass.getUserHelper = {userHelperMock}
}
确保您正在呼叫getUserHelper()
并不直接访问私有userHelper
媒体资源。明确这样做可能是个好主意:
password nullable: false, blank: false, validator: {pwd, userInstance ->
return this.getUserHelper().validatePassword(pwd)
}
@dmahapatro使用defineBeans{...}
的答案是最佳方式,但我认为由于this grails bug而无效...
将bean直接注入测试的另一个建议只适用于扩展grails.plugin.spock.IntegrationSpec
的集成测试。