SpringBoot-Spring Boot統合テストで@Transactionalを使用しない

テストの実行@Transactional 中、テストクラスの注釈により、テスト  内のEntity データの操作が  メモリ内で完了し、最終的にcommit 操作実行されなくなります  。つまり、Entity データ永続化されず  、テストの動作と実際のアプリケーションになります。の行動に一貫性がない。

トランザクション管理は、アプリケーション開発に不可欠な設計であり、データベースの永続化処理の標準です。アプリケーション開発はデータCRUD(追加、削除、変更、検査)と切り離せないものであり、トランザクションのACID性質により、データと関連データの整合性をより確実に保証できることがわかっています同生共死単一のトランザクションのライフサイクルは、主に3つの段階に分かれていますBEGIN TRANSACTION ->  COMMIT TRANSACTION ->  ROLLBACK TRANSACTION

Spring Bootトランザクションの使用は命令型宣言型に分けられますが、一般的な方法は宣言型注釈(@Transactional)です。トランザクション管理は、アプリケーション層とテストの両方で使用できます。

テスト間の独立性を確保するために、テスト間のデータは互いに影響を受けません。多分あなたはこのようなテストを書いたでしょう:

@SpringBootTest
@ActiveProfiles("test")
@Transactional
public class UserControllerTest { }

@Transactional データ永続化操作を切り捨てることにより、テストが互いに対立し、データが互いに影響を及ぼさないという問題が解決されます。ただし、この方法には副作用あります。つまり、データ永続化のプロセスは真実ではなくなり、プロセスはなくなりcommitます。これは以下につながります:

  • Entity アソシエーション間の関係、一意インデックスと主外部キー間のアソシエーションの正確性は保証されません 
  • Entity 作成時間、更新時間、およびバージョン付き(楽観的ロック)割り当てロジックの正確性は保証できません 
  • 我々はそれを保証することはできません  Entity が存在する  @Transient 論理注釈属性の精度の割り当て
  • テストデータは実際のシーンでは問題ありません
  • テストでは、単一のトランザクションで準備されたデータを複数のスレッド間で共有することはできません。

……

次に  Spring 紹介する問題領域をテストトランザクション管理をどのような本来の意図?どのような問題解決するためにそれを導入する必要がありますか?公式ドキュメントはトランザクション管理を紹介してい  ます

画像の説明

公式文書によると、テスト実行を解決するために、プログラムは実際のデータベースにアクセスし、データの状態を変更します。これは、その後のテストの問題に影響を与えます。

実際、ここで批判的思考をする必要があります。なぜテストを実行するときに実際のデータベースにアクセスする必要があるのですか?テスト間のデータが互いに影響するのはなぜですか?
各テストについて、各実行の前にクリーンなコンテキストまたは独立したコンテキストが必要です。データのクリーンアップと準備のプロセスがあり、テストは互いに分離されています。つまり、テストでインメモリデータベースまたは組み込みデータベースを使用できないのはなぜですか。テストケースを実行する前に純粋な土地が以前のテストデータの影響を受けないように、各テストを実行する前にデータベースのデータをクリーンアップしてみませんか?

答えはもちろんです!

 

最後に書く

どうやって?1つを実装  TruncateDatabaseServiceします。テーブルのデータを削除するだけで、テーブルの結果は削除しません。テストの基本クラスで@BeforeEach、を実行し  truncateます。ソーストランケートデータベース

元の記事952件を公開 1820年に賞賛 89万回の閲覧

おすすめ

転載: blog.csdn.net/Dream_Weave/article/details/105373383