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
사실, 허용됩니다. @PostConstuct 테스트는 통합 측면입니다. – loteq