单元测试Controller - MissingMethodException时无法模拟Grails服务方法

时间:2014-08-18 12:32:03

标签: unit-testing groovy grails-2.0 spock

测试控制器时收到以下错误消息 - 请参阅下面的代码。 我怎么能纠正这个? 当我从控制器(run-app)调用服务方法时,它工作正常。

例外:

  

groovy.lang.MissingMethodException:没有方法签名:   grails.test.GrailsMock.isOk()适用于参数类型:   (java.lang.String)值:[H] at ... VControllerSpec.test   东西(VControllerSpec.groovy:)

类: VControllerSpec

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

@TestFor(VController)
@Mock(VService)
class VControllerSpec extends Specification {

    void "test something"() {
        given:
        def vServiceMock = mockFor(VService)
        vServiceMock.demand.isOk { String yeah -> return true }
        controller.vService = vServiceMock.createMock()

        when:
        def isO = vServiceMock.isOk("H") 

        then:
        isO == true     
    }
}

课程: VService

import grails.transaction.Transactional

@Transactional
class VService {
    def isOk = { String yeah ->     
        def isO = false
        return isO
    }
}

谢谢, 史蒂夫

2 个答案:

答案 0 :(得分:3)

假设VController中有一项操作:

def myAction() {
    vService.isOk('Hello')
}

以下测试应该通过

void 'test service'() {
    given:
    def vServiceMock = mockFor(FormatService)
    vServiceMock.demand.isOk { String yeah -> return true }
    controller.vService = vServiceMock.createMock()

    when:
    def isO = controller.myAction() 

    then:
    isO == true
}

此处优化的内容很少,包括使用方法isOk代替闭包作为最佳做法。

答案 1 :(得分:0)

预计不会测试一个被嘲笑的方法。当我们模拟一个方法时,我们只是假设它的实现是正确的并且已经过测试(在其他一些单元测试中)。模拟的目的是将我们的测试重点限制在有限的代码行(通常是一种方法),在您的情况下是您的控制器操作。所以上面的测试用例可以写成:

假设你的行动是这样的:

def myAction(){
 [iso: vServiceMock.isOk()] // assuming isOk returns boolean true
}

void "test myAction"() {
        given:
        def vServiceMock = mockFor(VService)
        vServiceMock.demand.isOk { String yeah -> return true }
        controller.vService = vServiceMock.createMock()

        when:
        def model = controller.myAction() 

        then:
        model.iso   //you can skip comparison with true 
    }