2010年5月13日木曜日

GrailsのIntegrationTestで、ファイルのアップロードをテストする

grailsのバージョンは1.2.1
spockのバージョンは0.4-SNAPSHOT

import org.springframework.mock.web.MockMultipartHttpServletRequest
import org.springframework.mock.web.MockMultipartFile
import grails.plugin.spock.IntegrationSpec

class FileUploadControllerSpec extends IntegrationSpec {
  
    def controller

    def setup() {
        controller = new FileUploadController()
        controller.request.metaClass.mixin MockMultipartHttpServletRequest
    }

    def "アップロードされたファイルを保存する"() {
        when:
        MockMultipartFile file = new MockMultipartFile("html.attr.name", "originalFileName", "text/plain", "ファイルの内容".bytes)
        controller.request.addFile(file)
        and:
        controller.save()
        then:
        controller.responce.redirectedUrl == "/fileUpload/show/1"
    }
}

とりあえず。

2010年2月16日火曜日

IntegrationTestのときにタイムスタンプの自動設定を切りたい

Grailsのバージョンは1.2.1

lastUpdatedでソートしてるときとか、タイムスタンプの自動設定を切りたいんです。

[DomainClass]が何かのドメインだとして、
DomainClass.mapping.autoTimestamp(false)

まあGroovy的には当然かもですが。

2010年1月10日日曜日

Grailsの統合テスト内で、タグライブラリを呼び出す

Grailsのバージョンは1.2.0

備忘録的なメモ

タグライブラリやコントローラーのIntegration-Test書いてると、テストの中で標準(g)のタグライブラリ呼び出したくなることありませんか?あんまないか。


import org.codehaus.groovy.grails.commons.ApplicationHolder
import org.codehaus.groovy.grails.web.taglib.NamespacedTagDispatcher

class CustomTagLibSpecification extends GroovyPagesSpecification {
  NamespacedTagDispatcher g = ApplicationHolder.application.mainContext.getBean('gspTagLibraryLookup').lookupNamespaceDispatcher('g')

 def "仕様かきかき"() {
  message = g.message(code:"message.properties.message.code")
  ...
 }
}


上のはSpockの仕様ですけど、普通のGroovyPagesTestCase使ったテストケースでもいけるんじゃないかと。まあ、applyTemplate使ってもいいすけど。
コントローラ内だったら、なんにもしなくても message(code:"ほげほげ") でタグライブラリ呼び出せるんだけど…

もっといい方法ありましたら教えてくださいです。

2009年12月23日水曜日

Grailsのtest-appで、コンソールにstacktraceを出す

Grailsのバージョンは1.2.0.RC2

Grailsには、組み込みのテスト実行環境がついています。
Grailsをインストールして、Grailsのプロジェクトを作成して、
コンソールで"test-app"と打ち込むだけでテストが実行されます。

んですが、このテスト、実行してエラーがでても、コンソールにスタックトレースがでないんですよね。

testSample...FAILED

つー、そっけない一行がでるだけ。なんでやねん。

というわけで、Grailsのテストイベントを取ってスタックトレースを出してみます。

1.スタックトレースを出力するためのイベントリスナを作成する。
以下のようなスタックトレース出力クラスを作ります
package testsupport
import grails.build.GrailsBuildListener;
public class StackTraceDumper implements GrailsBuildListener {
    void receiveGrailsBuildEvent(String name, Object[] args) {
        if (name == 'TestFailure') {
            this.doTestFailure(*args)
        }
    }
    protected doTestFailure(String name, failure, boolean isError) {
        failure?.printStackTrace()
    }
}

2.上記イベントリスナをコンパイル
なんか、イベントリスナだけは前もってコンパイルしとかないと失敗しました。
[grails-project]/src/groovyの下に入れて"grails compile"を実行してもいいし、
jarにして[grails-project]/libにいれてもいいと思います。

3._Events.groovyスクリプトの記述
上記イベントリスナを設定します。
[grails-project]/scripts/_Events.groovyに以下を記述
import testsupport.StackTraceDumper
eventListener.addGrailsBuildListener(new StackTraceDumper())

4.test-appコマンドを、-echoErrオプション付きで実行する
Grails1.2.0から、echoErrオプションで標準エラーを出力できるようになりました。
"test-app -echoErr"と激しく打ち込み。
テストクラスを限定したり、ユニットテストだけ実行したりできます
"test-app [TEST CLASS] -echoErr"
"test-app unit: -echoErr"

で、スタックトレースがでるはず…


ちなみに、spockプラグインを使うと、powerassertsっぽいかっこいいスタックトレースになります。
こんな↓


あ、[grails-project]/scripts/_Events.groovyの仕様とかよく分かってないんで、突っ込みどころあったら突っ込んでくらはい

2009年12月8日火曜日

[Grails] GSP部分テンプレート内のitがときどき消滅する件

grailsのバージョンは1.2-M4

grailsで部分テンプレート「/share/_book.gsp」を表示するとき、



とかやると思います。
このとき、部分テンプレート「/share/_book.gsp」内の変数「it」にbookが自動で設定されるわけですが、
この「it」にアクセスできないことがあるようです。

具体的には、部分テンプレート「/share/_book.gsp」内で

${it.title.encodeAsHTML()}

というふうに、linkタグを使っているときにlinkタグテキスト部内のit(it.title.encodeAsHTML())にアクセスできないみたいです。この場合、次のようにdelegateからアクセスする必要があります。

${delegate.it.title.encodeAsHTML()}


テキスト部は、クロージャになってタグライブラリの引数に渡されるので、delegateの差し替えなどしていない場合上のようになる…のかな?

2009年11月6日金曜日

Grails + easyb でイミフなエラー(MultipleCompilationErrorsException)が出る件

Grailsのバージョンは1.2-M3
EasyB + Grails Testingプラグイン(grails-easyb)のバージョンは1.1

ちょっと前、GrailsでRSpec的なBDDができたらいいなぁ、的なこと言ってたんですが、どうやら"easyb" というBDDフレームワークがあって、Grailsでも使用できる模様。([Java][Groovy][BDD] Grails におけるドメインクラスのユニットテスト - Grails標準テストと Easyb プラグイン使用)

人によるかもですが、私の場合xUnit系のテストケースよりはBDDのスペックの方が断然書きやすいので、早速飛びついてみました。
easyb公式ページなどを参考に、簡単なシナリオを書いてみる…

で、タイトル通り怒られました。このメッセージがよく分からない…
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, Script1.groovy: 7: unexpected token: } @ line 7, column 5.
グーグル先生とかに相談してみたんですがさっぱり。
適当に試行錯誤してみました。まずコレ。
scenario "TestScenario", {
    given "TestGiven", {
    }
    when "TestWhen", {
    }
    then "TestThen", {
        "test".shouldBe("test")
    }
}
このコードなら通してくれました。
だから何?って感じの超テストコードなんですが、ここから段々デコレーションしてみます。

といいますか、どうやら日本語が含まれてるとだめっぽい。コメントすら無理
でもシナリオ名に日本語使ったとき、たまに通ることもある…

あーもうだめだ、再現性ないとかお試しで頑張るには手強すぎる。
シナリオの書き方が違ってるのか?コメントはどこどこに入れてはいけないとか…そんなバ
サービスのインジェクションとかどうするのかなー、とか他にもいろいろ調べたかったんですけど、とりあえず様子見ということで。

しばらく標準のテストで進めるか…

2009年11月3日火曜日

[Grails] Integration Test のテストケースは、GrailsUnitTestCaseでなくGroovyTestCase を継承するらしい

Grailsのバージョンは1.2-M3

情報元はここ
http://agileice.blogspot.com/2009/09/grails-integration-testing.html

なんか、GrailsのIntegrationTestで、Config.groovyに設定した定義情報が使えないなあ、って思ってネットサーフィンしてたら、上記のページを発見。

テストケースの継承元を間違うと、テストケースのtearDownでConfig.groovyの設定情報がnullになってしまうらしいです。
  • GrailsUnitTestCaseとか、それ継承してるControllerUnitTestCaseとか
    Unitテストのみに使用
  • GroovyTestCase
    Integration Test で使用
ポイントは、Integration Testのテストケース全部にGroovyTestCase を使うことですかね。
一個でもGrailsUnitTestCaseのが混じってると、その後のテストケースで設定情報が消えます。

最近のGrailsだと、コントローラーやサービス作成時にUnit Testを生成するから、そのファイルをIntegration Testの方に移動したりしているうちに段々ごっちゃになってそう。