Reputation: 3842
I am creating unit test for this (working fine) Grails service :
class CommonCodeService {
def gridUtilService
def getList(def params){
def ret = null
try {
def res = gridUtilService.getDomainList(CommonCode, params)
def rows = []
def counter = 0
res?.rows?.each{ // this is line 15
rows << [
id: counter ++,
cell:[
it.key,
it.value
]
]
}
ret = [rows: rows, totalRecords: res.totalRecords, page: params.page, totalPage: res.totalPage]
} catch (e) {
e.printStackTrace()
throw e
}
return ret
}
}
This a method from collaborator GridUtilService
:
import grails.converters.JSON
class GridUtilService {
def getDomainList(Class domain, def params){
/* some code */
return [rows: rows, totalRecords: totalRecords, page: params.page, totalPage: totalPage]
}
}
And this is my (not working) unit test for it :
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import com.emerio.baseapp.utils.GridUtilService
@TestFor(CommonCodeService)
@Mock([CommonCode,GridUtilService])
class CommonCodeServiceTests {
void testGetList() {
def rowList = [new CommonCode(key: 'value', value: 'value')]
def serviceStub = mockFor(GridUtilService)
serviceStub.demand.getDomainList {Map p -> [rows: rowList, totalRecords: rowList.size(), page:1, totalPage: 1]}
service.gridUtilService = serviceStub.createMock()
service.getList() // this is line 16
}
}
When I run the test it shows exception :
No such property: rows for class: com.emerio.baseapp.CommonCodeServiceTests
groovy.lang.MissingPropertyException: No such property: rows for class: com.emerio.baseapp.CommonCodeServiceTests
at com.emerio.baseapp.CommonCodeService.getList(CommonCodeService.groovy:15)
at com.emerio.baseapp.CommonCodeServiceTests.testGetList(CommonCodeServiceTests.groovy:16)
It seems the mocked GridUtilService
returns CommonCodeServiceTests
instance instead of Map
. What is wrong with my unit test?
Upvotes: 0
Views: 2004
Reputation: 3171
It looks like you need to fix your method params for the mocked getDomainList()
call. You have it as Map m
, but it probably needs to be Class c, Map m
.
From docs,
The closure arguments must match the number and types of the mocked method, but otherwise you are free to add whatever you want in the body.
Why a miss on the arguments behaves the way it does is a stumper. I can replicate your problem using my own stripped-down classes. I also found that the returned type for a call on the method when there's a param miss is a closure of the test class, which, for my simple case at least, can then be .call()
'ed to get the desired (mocked) result. I'm not sure if this behavior supports some kind of functionality or is a bug. It's certainly confusing.
Upvotes: 1