質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JUnit

JUnitは、Javaで開発されたプログラムのユニットテストを行うためのアプリケーションフレームワークです。簡単にプログラムのユニットテストを自動化することができ、結果もわかりやすく表示されるため効率的に開発時間を短縮できます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

1回答

5300閲覧

Spring BootのTransactionのテスト方法について

WalterMontes

総合スコア25

JUnit

JUnitは、Javaで開発されたプログラムのユニットテストを行うためのアプリケーションフレームワークです。簡単にプログラムのユニットテストを自動化することができ、結果もわかりやすく表示されるため効率的に開発時間を短縮できます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2021/06/19 01:16

DBにデータを登録している時にエラーが発生したらロールバックを行いたいので、@Transactionalを使おうと思うのですが、
本当にロールバックが発生するか確認するためにJunitでこのテストを書きたいです。
以下のqiitaの記事にあるようなテスト対象のメソッド中にDBに登録しているメソッドを2つ呼び出している場合は、1つ目を正常に実行させて、2つ目が呼ばれた時にRuntime exceptionを発生させてロールバックを実現しています。
https://qiita.com/shimi58/items/60ea681c74188c4ea8bc
私が行いたいのは、以下のように100件ずつデータを登録するときのロールバックのテストです。
100件登録させて、101件以降のデータを登録中にロールバックを発生させて、テーブルの内容がテスト実行開始時の状態になっているかを確認したいです。
------------Service class--------------------------

@Slf4j @Service public class SampleService { @Autowired SampleLogic sampleLogic; @Transactional public CommandType execute() { try { //get items List<ItemEntity> itemEntities = sampleLogic.getItems(); //save item data sampleLogic.itemSave(itemEntities); } catch (Exception e) { log.error("Error Happened!!!", e); return CommandType.FAILURE; } return CommandType.SUCCESS; } }

-----logic class----------------------------------------

@Component public class SampleLogic { @Autowired SampleRepository sampleRepository; public List<ItemEntity> getItems() { List<ItemEntity> itemEntities = new ArrayList<>(); for(int i = 0; i < 1000; i++) { itemEntities.add(new ItemEntity(String.valueOf(i), "itemName")); } return itemEntities; } public void itemSave(List<ItemEntity> itemEntities) { Iterables.partition(itemEntities, 100).forEach(list -> { // save data per 100 sampleRepository.saveAll(itemEntities); }); } }

-----test class----------------------------------------

@ExtendWith(SpringExtension.class) @TestExecutionListeners({DirtiesContextTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, TransactionDbUnitTestExecutionListener.class}) @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) public class SampleServiceTest { @InjectMocks private SampleService sampleService; @Test @DatabaseSetup("/itemPrep.xml") @ExpectedDatabase(value = "/testdata/CustomerServiceTest/init-data", assertionMode=DatabaseAssertionMode.NON_STRICT) void whenSaveMethodCalledRollBackHappen() { // // Assertions.assertEquals(CommandType.FAILURE, sampleService.execute()); } }

以下のようにメソッドの呼び出し回数によって異なる結果を返す方法でできるか試したのですが、List.classをモックするとitemSaveメソッドが実行されず、うまくいきませんでした。。もしどこか間違っていればご指摘お願いします。
https://reasonable-code.com/mockito-consecutive-calls/

@Test @DatabaseSetup("/itemPrep.xml") @ExpectedDatabase(value = "/testdata/CustomerServiceTest/init-data", assertionMode=DatabaseAssertionMode.NON_STRICT) void whenSaveMethodCalledRollBackHappen() { // List<ItemEntity> itemMockList = Mockito.mock(List.class); for(int i = 0; i < 100; i++) { Mockito.when(itemMockList.get(i)) .thenReturn(new ItemEntity(String.valueOf(i), "itemName")); } Mockito.when(itemMockList.get(101)).thenThrow(new RuntimeException()); //make sure execute method returns failure and item table is roll backed Assertions.assertEquals(CommandType.FAILURE, sampleService.execute()); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

@TransactionalはRDBのトランザクションの機能を呼び出しているだけなので、モックしてDBアクセスを無くすと機能しません。

投稿2021/06/21 21:20

rysh

総合スコア874

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問