我如何在服务grails中的域中模拟获取方法

时间:2018-03-06 17:13:35

标签: grails groovy specifications

我尝试运行服务的规范测试,但是当运行测试时,我在获取UnitMeasure域的方法后收到nullpointer。

我试图模仿这种静态方法但不起作用

我写下这些代码:

我的服务是ValidationService:

class ValidationService {
    def validateLogistic(def logisticComposition,def logisticCompositionChild, def json, def params) {
        validateNetWeightAndNetWeightPallet(logisticComposition)
    }

    def test(def logisticComposition) {

    if(logisticComposition?.netWeightUnitMeasure?.conversionFactor > 0) {

    UnitMeasure netWeightUnitMeasure = UnitMeasure.get(logisticComposition.netWeightUnitMeasure.id)

    if(netWeightUnitMeasure.conversionFactor != null)
        throw new LogisticValidationException("Invalid field value")
}}

我的测试是ValidationServiceSpec扩展了规范

@TestFor(ValidationService)
@Mock(LogisticComposition)
class ValidationServiceSpec extends Specification{
    def service
    JSONObject json

    def setup() {
        service = new ValidationService()
        json = new JSONObject()
        json.addLevel = true
    }

    def cleanup() {
    }


    void "validate logistic when net weigth master more than net weigth pallet"() {
        setup :
            UnitMeasure measure = new UnitMeasure()
            measure.conversionFactor = 1
            measure.abbreviation = "GR"
            measure.id = 1

            GrailsMock mockLocation = mockFor(UnitMeasure)
            mockLocation.demand.static.get() { int id -> return measure;
            }

        when:
            LogisticComposition logi = new LogisticComposition();
            logi.volume = new BigDecimal(100)
            logi.volumeUnitMeasure = measure;
            logi.volumeUnitMeasure.id = 1
            logi.gtin = "999999"
            logi.packing = new Packing()
            logi.amount = 1
            logi.height = new BigDecimal(100)
            logi.heightUnitMeasure = measure

            logi.width = new BigDecimal(100)
            logi.widthUnitMeasure = measure

            logi.depth = new BigDecimal(100)
            logi.depthUnitMeasure = measure

            logi.netWeight = new BigDecimal(100)
            logi.netWeightUnitMeasure = measure

            logi.netWeight = new BigDecimal(1000)
            logi.netWeightUnitMeasure = measure

            logi.netWeightPallet = new BigDecimal(100)
            logi.netWeightPalletUnitMeasure = measure 

            def params = new HashMap()
            params.addLevel = false

            service.test(logi)
        then:
            thrown LogisticValidationException
    }

错误:

   Running without daemon...
| Compiling 1 source files
| Compiling 1 source files.
| Running 2 unit tests...
| Running 2 unit tests... 1 of 2
| Failure:  validate logistic when net weigth master more than net weigth pallet(br.com.itemone.ValidationServiceSpec)
|  Expected exception of type 'br.com.itemone.LogisticValidationException', but got 'java.lang.NullPointerException'
    at org.spockframework.lang.SpecInternals.checkExceptionThrown(SpecInternals.java:79)
    at org.spockframework.lang.SpecInternals.thrownImpl(SpecInternals.java:66)
    at br.com.itemone.ValidationServiceSpec.validate logistic when net weigth master more than net weigth pallet(ValidationServiceSpec.groovy:70)
Caused by: java.lang.NullPointerException: Cannot get property 'conversionFactor' on null object
    at br.com.itemone.ValidationService.test(ValidationService.groovy:35)
    at br.com.itemone.ValidationServiceSpec.validate logistic when net weigth master more than net weigth pallet(ValidationServiceSpec.groovy:68)
| Completed 1 unit test, 1 failed in 0m 3s
| Tests FAILED  - view reports in 

我怎么能嘲笑这个方法?有任何想法吗?

2 个答案:

答案 0 :(得分:0)

由于您正在ValidationServiceSpec中测试ValidationService,因此Grails框架会在单元测试中自动注入服务。

@TestFor(ValidationService)
@Mock(LogisticComposition)
class ValidationServiceSpec extends Specification{
// def service
JSONObject json

def otherService          // if you need to use other service in this unit test

// only if this service has dependency injection with other service
static doWithSpring = {
    otherService(OtherService)
}

def setup() {
    //service = new ValidationService()

    // this is not required if you do not call methods on this service within this unit test file
    otherService = Holders.grailsApplication.mainContext.getBean("otherService")
    json = new JSONObject()
    json.addLevel = true
}

def cleanup() {
}


void "validate logistic when net weigth master more than net weigth pallet"() {
    setup :
        UnitMeasure measure = new UnitMeasure()
        measure.conversionFactor = 1
        measure.abbreviation = "GR"
        measure.id = 1

        GrailsMock mockLocation = mockFor(UnitMeasure)
        mockLocation.demand.static.get() { int id -> return measure;
        }

    when:
        LogisticComposition logi = new LogisticComposition();
        ...
        service.test(logi)        // this is automatically injected
    then:
        thrown LogisticValidationException
}

答案 1 :(得分:0)

如果你不想深入研究(GORM)嘲笑,你可以使用简单的groovy元编程:

UnitMeasure.metaClass.static.get = { long id -> new UnitMeasure(...) }