programing

컨버터를 사용하는 Grails 서비스를 테스트하려면 어떻게 해야 합니까?

skycolor 2023. 3. 28. 21:31
반응형

컨버터를 사용하는 Grails 서비스를 테스트하려면 어떻게 해야 합니까?

서드파티 서비스를 사용하여 HTTP 콜을 실행하여 전자 메일을 발송하는 Grails 서비스가 있습니다.

class EmailService {
    def sendEmail(values) {
        def valueJson = values as JSON
        ... // does HTTP call to 3rd party service
    }
}

이 서비스를 테스트하기 위해 유닛 테스트를 작성했습니다(통합 테스트에서는 휴지 상태 및 전체 도메인 프레임워크가 회전하므로 필요 없습니다).

@TestFor(EmailService)
class EmailServiceTests {
    void testEmailServiceWorks() {
        def values = [test: 'test', test2: 'test2']
        service.sendEmail(values)
    }
}

단, 이 유닛테스트를 실행하면 이 예외와 함께 이 유닛테스트를 실행하려고 하면 실패합니다.as JSON변환:

org.disc.disc.disc.glUnhandled Exception : org.codehouse.groovy.grails.web.inters. 예외.Converter Exception:변환할 수 없는 클래스의 개체: java.util.Linked Hash Map

그런 다음 유닛 테스트를 다시 작성하여 다음 작업을 수행합니다.

void testEmailServiceWorks() {
    def value = [test: 'test', test2: 'test2']
    def valueJson = value as JSON
}

그리고 같은 예외는 그것이 그 일을 하려고 할 때 발생한다.as JSON변환.

이 예외가 발생하는 이유와 해결 방법을 아는 사람이 있습니까?

서비스를 테스트하고 있는 경우에도@TestMixin(ControllerUnitTestMixin)테스트 클래스에 주석을 달아 Grails가 JSON 컨버터를 설정할 수 있도록 합니다.

도메인 프레임워크가 회전할 때 as JSON 매직이 생성됩니다.

테스트를 통합 테스트로 변경하거나 asType을 조롱해야 합니다.

def setUp(){
    java.util.LinkedHashMap.metaClass.asType = { Class c ->
        new grails.converters."$c"(delegate)
    }
}

TreadDown에서 청소하는 것을 잊지 마십시오. 테스트 스위트에서는 메타프로그래밍 누출이 발생하지 않도록 하십시오.

def tearDown(){
    java.util.LinkedHashMap.metaClass.asType = null
}

편집: 미래에서 온 경우 다음 답변을 고려하십시오.https://stackoverflow.com/a/15485593/194932

Grails 3.3.x로서grails-test-mixins플러그인은 더 이상 사용되지 않습니다.@이행가이드를 참조해 주세요.

이 문제를 해결하기 위해 구현해야 합니다.GrailsWebUnitTestGrails Testing Support Framework에서 제공되고 있습니다.

setUp()에서 JSON을 초기화할 수 있습니다.ObjectMarshaller를 구현하는 마샬러는 다양합니다.JSON 변환이 기능하려면 ConverterConfiguration에 추가해야 합니다.

http://grails.github.io/grails-doc/2.4.4/api/index.html?org/codehaus/groovy/grails/web/converters/marshaller/json/package-summary.html

예:

 DefaultConverterConfiguration<JSON> defaultConverterConfig = new  DefaultConverterConfiguration<JSON>()
 defaultConverterConfig.registerObjectMarshaller(new CollectionMarshaller())
 defaultConverterConfig.registerObjectMarshaller(new MapMarshaller())
 defaultConverterConfig.registerObjectMarshaller(new GenericJavaBeanMarshaller())

 ConvertersConfigurationHolder.setTheadLocalConverterConfiguration(JSON.class, defaultConverterConfig);

방금 이런 상황에 부딪혔는데 정말 구현하기 싫었어요.GrailsWebUnitTest여기서의 다른 답변에서 권장하는 바와 같이.서비스 테스트는 가능한 한 '순수'로 유지하고 싶습니다.결국 이렇게 됐어요.

void setupSpec() {
    defineBeans(new ConvertersGrailsPlugin())
}

void cleanupSpec() {
    ConvertersConfigurationHolder.clear()
}

이 방법은 구현 시 후드 아래에서 이루어집니다.GrailsWebUnitTest(경유)WebSetupSpecInterceptor그리고.WebCleanupSpecInterceptor).


즉, 변환기는 주로 컨트롤러와 다른 형식의 데이터를 투과적으로 반환하기 쉽게 하기 위해 웹 계층에서 사용하는 것으로 보입니다.테스트 중인 서비스에 애초에 변환기가 필요한 이유를 고려해 볼 필요가 있습니다.

예를 들어 JSON 컨버터를 사용하여 일부 데이터를 문자열에 직렬화하여 데이터베이스의 단일 필드에 저장했습니다.그것은 컨버터의 적절한 유저가 아닌 것 같기 때문에, 방법을 변경할 예정입니다.서비스 테스트에서 컨버터를 사용할 수 있도록 하는 것은 테스트 범위를 개선하기 위한 임시 솔루션입니다.

"render myMap as JSON"을 호출하는 컨트롤러를 유닛 테스트하려고 할 때 동일한 오류가 발생했습니다.Grails 1.3.7을 사용하고 있는데, 다른 어떤 솔루션도 다른 문제를 일으키지 않고는 작동하지 않았습니다.현재 Grails 업그레이드는 우리의 대안이 아니었다.

솔루션에서는 다음과 같이 'JSON'이 아닌 JSON Builder를 사용했습니다.

render(contentType: "application/json", {myMap})

http://docs.grails.org/latest/guide/theWebLayer.html#moreOnJSONBuilder 를 참조해 주세요.

(이것이 오래되었다는 것은 알지만, 해결책을 찾기 위해 이곳에 왔기 때문에 다른 사람들도 마찬가지입니다.)

언급URL : https://stackoverflow.com/questions/11785708/how-do-i-unit-test-a-grails-service-that-uses-a-converter

반응형