2012-03-26 20 views
4

私は非常に簡単なセットアップ、つまりサービス上のメソッドを呼び出すコントローラを持っています。このサービスでは、オブジェクトをDBに保存し、注入されたJMSTemplateを使用してJMSメッセージをキューに保存した後にキューに送信します。このサービスでは、デフォルトでトランザクションが有効になっています。Grails:統合テストにおけるトランザクション

ActiveMQサーバーを停止して手動でテストすると、例外がスローされ、トランザクションがロールバックされ、オブジェクトがDBに保存されていないというネットエフェクトが発生します。すべての良い。

しかし、ActiveMQを使用した統合テスト(これはまだダウンしています)を実行すると、コントローラーを呼び出した後にオブジェクトがDBに保存されていないことを確認するためのアサーションカウントが1であることを確認できませんでした。私は、カウントが0であることを確認するために、テストの開始時に別のアサートを追加してテストを開始すると、DBにこれらのオブジェクトがないことを確認しました。

期待される振る舞い(おそらく、統合テスト環境におけるトランザクションの性質による)、あるいは私は潜在的に何か間違ったことをしていますか? JMSサーバーがダウンしており、RuntimeExceptionであるため、例外がスローされています。

Grails integration tests and transactionsこの場合、統合テストでのトランザクション動作をテストするためのベストプラクティスに関する提案はありますか?

+0

正しく覚えていれば、テストが完了するまでトランザクションはロールバックされません。したがって、アサーションを実行すると、トランザクションがまだロールバックされていないため、データがdbに保存されたように見えます。 – GreyBeardedGeek

+0

はい、テストとコントローラの両方で同じトランザクションが使用されているようです。このような場合に使用するための標準的なパラダイムがあるかどうか疑問に思っていました。私はコントローラのコードをテストのためだけに変更して、新しいトランザクションが必要になることを望んでいません。 – Rama

+1

このブログポストhttp://www.fepede.net/blog/?p=27では、テストを非トランザクションにする方法を示しています。コントローラとサービスが独自のトランザクションを持つようになります(テストのトランザクションを使用しない) 。欠点は、例外がスローされないと、トランザクションがコミットし、自分でクリーンアップする必要があるということです。 – GreyBeardedGeek

答えて

7

コメントが答えを公開しているので、誰もが答えるのではなく、なぜコメントしたのかよくわかりません。私は飛び込んで答えの点についていくつもりです!

はい、Spockテストでは、whens、thens、givensなどのテスト全体がすべて同じトランザクションから使い果たされます。そのため、テストが完了するまで、あなたが望んでいるロールバックは表示されません。

テストクラスの上部に「static transactional = false」を追加することで、テストを非トランザクションに設定できます。もちろん、テストの実行後(データベースの衛生管理が重要な場合)には、データベースをクリーンアップする必要があります。ここで大きな問題となるのは、Grails IntegrationSpecクラスにバグがあり、トランザクションをfalseに設定しようとするたびに爆発するということです。

Grails 2.3 IntegrationSpec cannot be transactional false基本的に

、独自のクラスにgrails.test.spock.IntegrationSpecのコードのすべてをコピーしてのトランザクションの自然を尊重バージョンとのいくつかのメソッドを置き換えます。これは、SO、その問題の解決策を持っていますテスト。

関連する問題