Подтвердить что ты не робот

Как сделать unit test услугу Grails, которая использует конвертер?

У меня есть служба Grails, которая отправляет электронные сообщения с помощью сторонней службы, выполняя HTTP-вызов:

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

Я написал unit test, чтобы протестировать эту службу (поскольку интеграционный тест включает Hibernate и всю инфраструктуру домена, которые мне не нужны):

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

Однако, когда я выполняю этот unit test, он не работает с этим исключением, когда пытается выполнить преобразование as JSON:

org.apache.commons.lang.UnhandledException: org.codehaus.groovy.grails.web.converters.exceptions.ConverterException: Неконвертируемый Объект класса: java.util.LinkedHashMap

Затем я повторно написал свой unit test, чтобы сделать следующее:

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

И я получаю такое же исключение, когда он пытается выполнить преобразование as JSON.

Кто-нибудь знает, почему я получаю это исключение, и как я могу это исправить?

4b9b3361

Ответ 1

Магия JSON создается при развертывании инфраструктуры домена.

Вам нужно либо сменить тест на интеграцию, либо высмеять asType.

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

Rember, чтобы очистить себя после tearDown, вам не хотелось бы метапрограммировать утечки в вашем тестовом наборе.

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

Изменить: Если вы пришли из будущего, рассмотрите этот ответ: fooobar.com/questions/208528/...

Ответ 2

Даже если вы тестируете службу, вы можете применить аннотацию @TestMixin(ControllerUnitTestMixin) к вашему тестовому классу, чтобы заставить Grails настроить конвертер JSON.

Ответ 3

вы можете инициализировать JSON в setUp(). Существуют различные маршаллеры, которые реализуют ObjectMarshaller, которые должны быть добавлены в преобразование ConverterConfiguration для преобразования JSON для работы.

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);

Ответ 4

Я получал ту же ошибку при попытке unit test контроллера, который вызывает "render myMap as JSON". Мы используем Grails 1.3.7, и ни одно из других решений не работало для меня, не внося никаких других проблем. Модернизация Grails для нас в настоящее время не является альтернативой.

Моим решением было использовать JSONBuilder вместо "как JSON", например:

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

См. http://docs.grails.org/latest/guide/theWebLayer.html#moreOnJSONBuilder

(Я понимаю, что это старый, но пришел сюда, чтобы найти решение, и, возможно, другие)