Unable to mock Grails Service method when unit testing Controller - MissingMethodException

故事扮演 提交于 2019-12-06 04:06:11

问题


Am getting the following error message when testing the controller - see below for code. How can I correct this? When I invoke the service method from the controller (run-app) and it works fine.

Exception:

groovy.lang.MissingMethodException: No signature of method: grails.test.GrailsMock.isOk() is applicable for argument types: (java.lang.String) values: [H] at ...VControllerSpec.test something(VControllerSpec.groovy:)

class: 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     
    }
}

class:VService

import grails.transaction.Transactional

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

Thanks, Steve


回答1:


Assuming there is an action in VController as:

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

below test should pass

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
}

There are few things to optimize here including using a method isOk instead of a closure as best practices.




回答2:


One is not expected to test a method which is being mocked. When we mock a method, we just assume its implementation is correct and has already been tested (in some other unit test). The purpose of mocking is to limit our focus of testing to limited lines of code (mostly commonly one method), in your case the your controller action. So the above test case could have been written as:

Assuming your action is like this:

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 
    }


来源:https://stackoverflow.com/questions/25363401/unable-to-mock-grails-service-method-when-unit-testing-controller-missingmetho

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!