Grails Spock测试控制器和服务

时间:2014-11-11 10:40:06

标签: unit-testing grails spock

您好我有一个名为ApiController的控制器,它使用一个名为ApiService的服务,如下所示:

def createCategory(){
        def jsonObj = request.JSON
        jsonObj.each{ key, value ->
            params.put(key,value)
        }
        render apiService.createCategory(params)
}

哪个工作正常。 但我似乎无法为它编写测试。

这是我有多远:

@TestFor(ApiController)
@Mock([Category,ApiService])   
class CategorySpec extends Specification {

    def setup() {
    }

    def cleanup() {
    }

    void "test"() {

        setup:
        def apiService = Mock(ApiService)

        when:
        request.method = 'POST'
        request.requestMethod = 'POST'
        params.categoryID = 'test'

        controller.createCategory()

        then:
        println(response)
        1==1

    }

由此我得到以下错误:

java.lang.NullPointerException: Cannot invoke method createCategory() on null object

这显然是因为它无法看到我的apiService bean。所以我的问题是我如何在Spock中做到这一点?

3 个答案:

答案 0 :(得分:7)

最有可能使用Transactional bughttps://github.com/grails/grails-core/issues/1501

ApiService apiService = new ApiService()
controller.apiService = apiService
apiService.transactionManager = Mock(PlatformTransactionManager) { getTransaction(_) >> Mock(TransactionStatus) }

这是一个临时修复(根据错误报告评论)......这对我有用:)

答案 1 :(得分:1)

这是我在Grails 2.4中的方法,在spec类上没有注释@Mock

when:
    def serviceMock = mockFor(ApiService)
    serviceMock.demand.createCategory { def params -> "output sample" }
    controller.apiService = serviceMock.createMock()
    controller.createCategory()

答案 2 :(得分:0)

ApiService在测试中被成功模拟但是你如何向控制器提供模拟?单位规格被剥夺了DI,你不能指望它自动装配。因此,

setup:
controller.apiService = Mock(ApiService)