2016-07-30 6 views
3

Config.groovy의 일부 구성 항목을 가져 와서 @PostConstuct으로 초기화하려는 서비스가 있습니다.Spock 유닛 테스팅을 사용하여 @PostConstruct를 사용한 Untestable grails (2.5.4) 서비스

또한 이러한 항목이 올바르게 구성되었는지 확인하고 예외가 발생하여 응용 프로그램이 잘못 구성되었음을 알 수 있습니다.

이 서비스에 대한 단위 테스트를 작성할 때 Spock에서 막 다른 골목에 섰습니다.

Spock은 분명히 @PostConstruct 메서드를 호출하지만 Shared Service 인스턴스에서만 테스트 한 다음 실제 인스턴스에서 테스트하는 모든 인스턴스 메서드를 실행합니다.

이 비뚤어진 부작용이 있습니다

내 초기화 코드를 하나 내가 공유 인스턴스를 초기화하기 위해 setupSpec를 추가하는 데 실패하거나 구성이 실제로 설정되어 있지 않은 있기 때문에, 시험 방법에서 실패하기 때문에 실패 그 인스턴스에.

여기 내 서비스입니다 :

package issue 

import org.codehaus.groovy.grails.commons.GrailsApplication 

import javax.annotation.PostConstruct 

class MyService { 
    GrailsApplication grailsApplication 
    String property 

    @PostConstruct 
    void init() { 
     println "Initializing... ${this}" 
     property = grailsApplication.config.myProperty 

//Enabling this business sanity check make the service untestable under Spock, because to be able to run, we need to initialize the configuration 
// of the shared instance - PostConstruct is only called on the shared instance for some reason. 
// But the execution of the method under test will not have the initialized property, because the service being executed is not the shared instance 
     if (property == "[:]") { 
      throw new RuntimeException("This property cannot be empty") 
     } 
    } 


    void doSomething() { 
     println "Executing... ${this}" 
     println(property.toLowerCase()) 
    } 
} 

여기 내 첫 번째 테스트입니다 :

package issue 

import grails.test.mixin.TestFor 
import spock.lang.Specification 

@TestFor(MyService) 
class MyServiceSpec extends Specification { 

    def setup() { 
     grailsApplication.config.myProperty = 'myValue' 
    } 

    void "It fails to initialize the service"() { 
     expect: 
     false // this is never executed 
    } 
} 

여기에 두 번째 테스트입니다 :

package issue 

import grails.test.mixin.TestFor 
import spock.lang.Specification 

@TestFor(MyService) 
class MyServiceWithSharedInstanceInitializationSpec extends Specification { 

    //Initializing the shared instance grailsApplication lets the @PostConstruct work, but will fail during method test 
    //because the instance that was initialized is the shared instance 
    def setupSpec() { 
     grailsApplication.config.myProperty = 'myValue' 
    } 

    void "It fails to execute doSomething"() { 
     when: 
     service.doSomething() 

     then: 
     def e = thrown(NullPointerException) 
     e.message == 'Cannot invoke method toLowerCase() on null object' 
     service.property == null 
    } 
} 

깨끗하게 할 수있는 방법이 있습니까? 아니면 단위 테스트를 진행하고이 이상한 상황을 조심스럽게 (느린) 통합 테스트를해야합니까? 당신은 여기 내 전체 Grails의 응용 볼 수 있습니다

: 내가 공유 인스턴스를 초기화하기 위해 setupSpec를 추가하는 데 실패하기 때문에

https://github.com/LuisMuniz/grails-spock-issue-with-postconstruct

답변

2

내 초기화 코드 중 하나가 실패하거나 테스트중인 방법에 실패 왜냐하면 구성이 실제로 해당 인스턴스에 설정되지 않았기 때문입니다.

내 조언은 당신이 방법의 논리와 기능을 테스트하지 @PostConstruct 작동 여부에 관계없이이 가장 이해하기 보이기 때문에 단순히, init 메소드를 호출하는 것입니다.

+0

사실, 허용됩니다. @PostConstuct 테스트는 통합 측면입니다. – loteq

관련 문제