テストの実行@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
ます。ソーストランケートデータベース: