5

Grails2.1.0の使用

コントローラからこれを行うようです:

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. 関連するモデルエントリについて複数のアサーションを作成することを困難にします。

コントローラがテンプレートをレンダリングするときに、テストケースからモデルのエントリをより直接的に取得する方法はありますか?

4

1 に答える 1

10

renderメソッドのコードを少し掘り下げます( )。をレンダリングしたときにのみがorg.codehaus.groovy.grails.web.metaclass.RenderDynamicMethod設定されていることがわかります。modelAndViewview

テンプレートをレンダリングすると、実際にnullのmodelAndViewが返されます。

この場合のモデルの検査には、Groovyを使用できると思いますmetaClass。アイデアは、元のメソッドをインターセプトし、値を格納してから、彼を呼び出すことです。

この質問に基づいて、私はこれを作成しました(テストされていない、調整が必要な場合があります):

@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'

}
于 2013-02-28T20:15:51.730 に答える