2016-11-05 17 views
2

私は(おそらく統合より機能テストをよりしかしです...)、次のテストはしているがあります問題になるかもしれませんが)問題は私がthenブロックにいるときです。新しい名前でConventionが見つかり、idが一致していますが、nameフィールドをテストすると、まだ古い名前があるために失敗しています。Grailsの3統合スペックは奇妙なトランザクションの動作

テストでドキュメントを読んでいるうちに、データがどのセッションに作成されるのかという問題があると思います。@RollbackにはBootStrapとは別のセッションがあるため、データは実際にゲル化していません。たとえば、テストのgivenブロックを介してデータをロードすると、コントローラーがRestBuilderによって呼び出されると、そのデータは存在しません。

私はこのようなテストをこのようにしてはいけない可能性がありますので、ご了承ください。

答えて

3

これは間違いなく機能テストです。サーバーに対してHTTPリクエストを行い、メソッド呼び出しを行わず、これらの呼び出しの影響についてアサーションを作成します。

機能テストで自動ロールバックを取得することはできません。テストはサーバーと同じJVMで実行されるかどうかに関わらず、1つのスレッドで行われ、別のスレッドで処理されるためです。 BootStrapのコードは、すべてのテストが実行されコミットされる前に一度だけ実行されます(トランザクションや自動コミットを使って変更を加えたため)、次に 'クライアント'テストコードが独自の新しいHibernateセッションとトランザクションテストインフラストラクチャが開始され(テストメソッドの最後にロールバックされます)、サーバーサイドコードは(OSIVのために)独自のHibernateセッションで実行され、コントローラとサービスが他のトランザクションで実行されてもよいし、単に自動コミットされてもよい。

おそらくここでは重要ではないが、Hibernate永続性テストで常に考慮すべき点の1つはセッションキャッシュです。 Hibernateセッションは第1レベルのキャッシュで、findByNameのような動的ファインダはおそらくフラッシュをトリガーしますが、テストでは明示的に指定する必要があります。しかし、キャッシュされた要素はクリアされず、新しいインスタンスを実際にロードしていない可能性があるため、このようなコードで誤検出の危険性があります。Hibernateはキャッシュされたインスタンスを返す可能性があります。 get()を呼び出すときは間違いありません。私はいつもflushAndClear()メソッドを統合関数ベースクラスに追加して、putブロックを呼び出してwhenブロックを呼び出すと、すべてがHibernateからデータベースにフラッシュされていることを確認してからクリアします実際のリロードを強制するセッション。ランダムドメインクラスを選択し、withSessionを使用します。

protected void flushAndClear() { 
    Foo.withSession { session -> 
     session.flush() 
     session.clear() 
    } 
} 

putは一つのスレッド/セッション/ TX、自分で実行ファインダで行われるため、これが効果を持つべきではありませんが、一般的に使用されるパターンでなければなりません。

+0

ありがとうBurt。それはいくつかのことをクリアするのに役立ちます。私が混乱していたのはGrails 2でした。統合と機能の間にかなりの明確な線がありました(機能テストはその時点で第一級の市民ではなかったため)。そしてGrails 3では、機能テストを作成するには '@ Integration'と' @Rollback 'をGebSpecのテンプレートに追加します。 – Gregg

+2

機能テストは主に第一級の市民ですが、テスト/機能フォルダを作成するにはプラグインが必要です。Grails 3では、統合と機能テストが同じフォルダを共有しており、Webサーバーが統合テストのために起動され、その違いがさらにぼやけていることは間違いありません。 –

+0

うわー、それはなぜ私が過去の仕事をロールバックすることができなかったのかを説明します。私はこれらの行に沿って何かが起こっていると考えました。これを明確にしてくれてありがとう。機能(API)テストデータのセットアップとロールバックのベストプラクティスはありますか?私は現在、GreggのようにBootStrap経由で自分のデータを設定しています。そして、テストに合格すると、API呼び出しによるクリーンアップブロックの変更を元に戻します。 –