2013-02-28 2 views
5

Использование Grails 2.1.0Проверка контроллера Grails, подтверждающая утверждение модели при рендеринге шаблона?

Кажется, что делает это от контроллера:

render(view: "someView", model: [modelEntry: "hello"]) 

позволяет мне сделать это в модульном тесте для этого контроллера:

controller.method() 
assert model.modelEntry == "hello" 

Однако, если Я меняю контроллер, чтобы сделать это:

render(template: "someTemplate", model: [modelEntry: "hello"]) 

Теперь модель экземпляр в тесте - пустой массив. Я довольно много разбираюсь в этом, и большинство решений, похоже, для Grails 1, часто с участием объекта modelAndView (которого нет в моем тесте) или renderArgs (то же).

Единственное решение, которое я нашел, чтобы вручную изменить точку зрения в тесте, как это:

views['_someTemplate.gsp'] = '${modelEntry}' 

, а затем сделать утверждения о строке. Но мне не нравится это решение, потому что:

  1. требует тест знает имя файла шаблона
  2. затрудняет для записи тестовых моделей, которые не имеют хорошего ToString() методы
  3. затрудняет сделать несколько утверждений о связанных записях модели.

Есть ли способ более прямого доступа к элементам в модели из тестового примера, когда контроллер отображает шаблон?

+0

'controller.modelAndView.model' не существует? –

+0

@ SérgioMichels правильно, 'controller.modelAndView' равно null. Имейте в виду, что это использует идиоматический стиль Grails 2, где тест объявляется как '@TestFor (WhateverController)', и тест ничего не расширяет. Я не уверен, работает ли модельAndView для grails 1 или почему я всегда вижу это предложение, но в этом случае Grail 2 этого типа нет. – Rod

ответ

9

Копаем немного в коде метода визуализации (org.codehaus.groovy.grails.web.metaclass.RenderDynamicMethod) Я вижу, что modelAndView настроен только при рендеринге view.

Оказание шаблона вернет нулевую модельAndView.

Чтобы проверить модель в этом случае, я думаю, вы можете использовать Groovy metaClass. Идея состоит в том, чтобы перехватить исходный метод, сохранить значение, а затем вызвать его.

на основе this question, я построил этот (не проверял, может понадобиться Цвет регулируется):

@TestFor(MyController) 
class MyControllerTests 

    def templateModel 

    @Test 
    void inspectTemplateModel() { 
    def originalMethod = MyController.metaClass.getMetaMethod('render', [Map] as Class[]) 
    controller.metaClass.render = { Map args -> 
     templateModel = args.model 
     originalMethod.invoke(delegate, args) 
    } 

    controller.method() 
    assert templateModel.modelEntry == 'foo' 

} 
+0

Да, это сработало. Удивительно, что это требует такого рода обмана. Я на самом деле сделал ваше решение еще дальше, вместо шаблонаModel я фактически присваиваю modelAndView на экземпляре контроллера, делая остальную часть кода работать так, как вы ожидали бы, если бы это было представление – Rod

+0

Ну, вы можете поднимите [JIRA] (http://jira.grails.org/browse/GRAILS), предложив лучший способ доступа к шаблонной модели для ваших тестов. Это красота улучшения :) –