使用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就是这样,我可以看到代码的位置..
答案 0 :(得分:0)
不确定,但是在创建实例后尝试模拟obj的实例是值得的
mockDomain(TransactionDetailCommand, [obj])
答案 1 :(得分:0)
尝试以这种方式组织您的测试:
def "Ensure that for issues / transfer transactions then serial/part numbers are required to match .. "(){
given: "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}
when: "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']
}
因为对象的创建和元编程都是设置动作。