Использование spock для модульного тестирования объекта команды. У меня есть строка в объекте команды..
какой-то код..
} else {
if ((val && obj.part) && obj.transactionType.transactionIsATransfer()) {
println "obj.part .. class is ${obj.part.getClass()} .. serial is ${val.getClass()}"
if(! isAValidPartSerialCombo(obj.part,val)) <-- line 79
return 'com.myStuff.TransactionDetailCommand.serialReference.not.for.part'
}
..
def isAValidPartSerialCombo {part, serialReference ->
return InventoryMaster.hasPartandSerial(part,serialReference)
}
У меня есть модульный тест, в котором я издеваюсь над зависимостью
def obj = new TransactionDetailCommand(transactionType: new TransactionType(type: 'Transfer', requireSerial: true),
serialReference: 'AAA', part: new Part(partNumber: 'AAA'))
obj.metaClass.isAValidPartSerialCombo = {a,b -> false}
and: "we try to validate the transaction "
obj.validate()
then: "we get an error on the transaction for the 'serialReference' property"
obj.errors['serialReference']
что мне выдает ошибку..
java.lang.IllegalArgumentException: object is not an instance of declaring class
at com.vantec.TransactionDetailCommand._clinit__closure1_closure7(TransactionDetailCommand.groovy:90)
at grails.test.MockUtils.addValidateMethod_closure87_closure114(MockUtils.groovy:1035)
at grails.test.MockUtils.addValidateMethod_closure87(MockUtils.groovy:1031)
at grails.test.MockUtils.addValidateMethod_closure88(MockUtils.groovy:1065)
at com.myStuff.transaction.TransactionDetailCommandSpec.Ensure that for issues / transfer transactions then serial/part numbers are required to match .. (TransactionDetailCommandSpec.groovy:79)
Однако, если я создаю отдельный фиктивный тест, он работает без проблем.
def "A simple test .. "(){
when:
def obj = new TransactionDetailCommand()
obj.metaClass.isAValidPartSerialCombo = {a,b -> false}
then: 'we get a false ..'
!obj.isAValidPartSerialCombo(new Part(),"AAA")
}
Кто-нибудь может пролить свет??
Спасибо
Полный тест...
def "Ensure that for issues / transfer transactions then serial/part numbers are required to match .. "(){
when: "The transaction type indicates a transfer and we supply a serial number and a part .."
def obj = new TransactionDetailCommand(transactionType: new TransactionType(type: 'Transfer', requireSerial: true),
serialReference: '12345', part: new Part(partNumber: 'PartA'))
obj.metaClass.isAValidPartSerialCombo = {a,b -> false}
and: "we try to validate the transaction "
obj.validate()
then: "we get an error on the transaction for the 'serialReference' property"
obj.errors['serialReference']
and: "the error is the correct one .."
'com.myStuff.TransactionDetailCommand.serialReference.not.for.part' == obj.errors['serialReference']
}
и ограничение, которое я тестирую..
serialReference nullable: true, validator: { val, obj ->
println "One .. "
if ((val == null || val.toString().isEmpty()) && obj.transactionType.requireSerial) {
println "Two .. "
return 'com.myStuff.TransactionDetailCommand.serialReference.required'
} else {
println "Three .. "
if ((val && obj.part) && obj.transactionType.transactionIsATransfer()) {
println "Four ..."
if(! isAValidPartSerialCombo(obj.part, val)){
println("Five .. ")
return 'com.myStuff.TransactionDetailCommand.serialReference.not.for.part'
}
}
}
return 'oops'
}
def isAValidPartSerialCombo = {part, serialReference ->
println "Six .."
// return InventoryMaster.hasPartandSerial(part,serialReference)
return true
}
Println просто для того, чтобы я мог видеть, куда идет код.
isAValidPartSerialCombo
статическим (поскольку валидатор находится в статическом контексте) и использоватьobj.metaClass.'static'.isAValidPartSerialCombo
? В противном случае я бы попробовал переопределить метакласс в классе вместо объекта. - person dmahapatro   schedule 06.05.2014