Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その26 )( 貸出希望書籍 CSV ファイルアップロード画面の作成5 )
概要
Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その25 )( 貸出希望書籍 CSV ファイルアップロード画面の作成4 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- 貸出希望書籍 CSV ファイルアップロード画面の作成
- テストの作成の続きです。
- 貸出希望書籍 CSV ファイルアップロード画面の作成
参照したサイト・書籍
spring-amqp/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/
https://github.com/spring-projects/spring-amqp/tree/master/spring-rabbit/src/test/java/org/springframework/amqp/rabbit- Spring AMQP の RabbitMQ 用ライブラリの GitHub にある test ディレクトリです。Spring AMQP + RabbitMQ のテストの方法が分からなかったので参考にしました。
Java Code Examples for org.springframework.amqp.rabbit.core.RabbitAdmin
http://www.programcreek.com/java-api-examples/index.php?api=org.springframework.amqp.rabbit.core.RabbitAdmin- Spring AMQP + RabbitMQ のテストの方法についてこちらのサイトも参考にしました。
- このサイトはサンプルが豊富な気がします。最近よく見に行きます。
The JMockit Testing Toolkit Tutorial
http://jmockit.org/tutorial.htmlJava Code Examples for org.springframework.test.web.servlet.request.MockMvcRequestBuilders
http://www.programcreek.com/java-api-examples/index.php?api=org.springframework.test.web.servlet.request.MockMvcRequestBuilders- MockMvcRequestBuilders によるファイルアップロードのテストの書き方を参照しました。Example 8 です。
目次
- InquiringStatusOfBookQueueService クラスのテストの作成
- BooklistService クラスのテストの作成
- BooklistController クラスのテストの作成
- 全てのテストが成功するか確認する
- commit、Push、Pull Request、マージ
- 次回は。。。
- メモ書き
手順
InquiringStatusOfBookQueueService クラスのテストの作成
src/main/java/ksbysample/webapp/lending/service/queue の下の InquiringStatusOfBookQueueService.java で「Create Test」ダイアログを表示し、テストクラスを作成します。
src/test/java/ksbysample/webapp/lending/service/queue の下に InquiringStatusOfBookQueueServiceTest.java が作成されます。
src/test/java/ksbysample/webapp/lending/service/queue の下の InquiringStatusOfBookQueueServiceTest.java を リンク先の内容 に変更します。
テストを実行します。InquiringStatusOfBookQueueServiceTest クラスのクラス名にカーソルを移動し、コンテキストメニューを表示後「Run 'InquiringStatusOfBookQueueServ...' with Coverage」を選択します。
テストが成功することが確認できます。
BooklistService クラスのテストの作成
src/main/java/ksbysample/webapp/lending/web/booklist の下の BooklistService.java で「Create Test」ダイアログを表示し、テストクラスを作成します。
src/test/java/ksbysample/webapp/lending/web/booklist の下に BooklistServiceTest.java が作成されます。
lending_app, lending_book テーブルをテストデータに入れ替えるための記述を table-ordering.txt に記述するのを忘れていたので追加します。src/test/resources/testdata/base の下の table-ordering.txt を リンク先の内容 に変更します。
1点注意事項として table-ordering.txt は外部キー制約で親子関係があるテーブルは子テーブルを下に書くようにします。そうしないとテーブルのデータを削除することができずテスト実行時にエラーが発生します。
アップロードファイルの MockMultipartFile クラスのインスタンスを生成するために BooklistCsvFileServiceTest のメソッドを利用できるようにします。src/test/java/ksbysample/webapp/lending/service/file の下の BooklistCsvFileServiceTest.java を リンク先の内容 に変更します。
今のままだとテストしにくいことに気づいたのでテストしやすい構成に変更します。まず src/main/java/ksbysample/webapp/lending/security の下に LendingUserDetailsHelper.java を作成します。作成後、リンク先の内容 に変更します。
次に src/main/java/ksbysample/webapp/lending/web/booklist の下の BooklistService.java を リンク先のその1の内容 に変更します。
データ登録後の確認用データを作成します。src/test/resources/ksbysample/webapp/lending/web の下に booklist/assertdata/001 ディレクトリを作成します。
src/test/resources/ksbysample/webapp/lending/web/booklist/assertdata/001 の下に table-ordering.txt, lending_app.csv, lending_book.csv を作成します。作成後、リンク先の内容 に変更します。
BooklistController クラス、BooklistService クラスで実装時にメソッド名と処理内容を2転、3転させていて修正し忘れていた部分があることに気づいたので修正します。src/main/java/ksbysample/webapp/lending/web/booklist の下の BooklistService.java を リンク先のその2の内容 に変更します。
src/main/java/ksbysample/webapp/lending/web/booklist の下の BooklistController.java を リンク先の内容 に変更します。
src/test/java/ksbysample/webapp/lending/web/booklist の下の BooklistServiceTest.java を リンク先の内容 に変更します。
テストを実行します。BooklistServiceTest クラスのクラス名にカーソルを移動し、コンテキストメニューを表示後「Run 'BooklistServiceTest' with Coverage」を選択します。
テストが成功することが確認できます。
BooklistController クラスのテストの作成
src/main/java/ksbysample/webapp/lending/web/booklist の下の BooklistController.java で「Create Test」ダイアログを表示し、テストクラスを作成します。
src/test/java/ksbysample/webapp/lending/web/booklist の下に BooklistControllerTest.java が作成されます。
最初にテストの構成を決めます。src/test/java/ksbysample/webapp/lending/web/booklist の下の BooklistControllerTest.java を リンク先のその1の内容 に変更します。
テストを実装します。src/test/java/ksbysample/webapp/lending/web/booklist の下の BooklistControllerTest.java を リンク先のその2の内容 に変更します。
テストを実行します。BooklistControllerTest クラスのクラス名にカーソルを移動し、コンテキストメニューを表示後「Run 'BooklistControllerTest' with Coverage」を選択します。
テストが成功することが確認できます。
全てのテストが成功するか確認する
最後に全てのテストが成功するか確認します。Project View のルートでコンテキストメニューを表示して「Run 'Tests in 'ksbysample...' with Coverage」を選択します。
OpenWeatherMapApiServiceTest だけエラーになりました。ログを見ると "401 Unauthorized" と出力されているので、どうも認証が必要になったようです。
http://openweathermap.org/api を見ると "To access the API you need to sign up for an API key if you are on a free or paid plan." と書かれていました。特にメインの機能とは関係がないので、今回はテストを実行対象外にします。
src/test/java/ksbysample/webapp/lending/service/openweathermapapi の下の OpenWeatherMapApiServiceTest.java を リンク先の内容 に変更します。
再度全てのテストを実行し、今度は成功することが確認できます。
※UniVocityParsersTest はライブラリの検証のために作成したテストなので、こちらも対象外にしました。Qiita に記事を書いたので、詳細は Java の CSV/TSV/固定長ファイル Parser ライブラリ uniVocity-parsers の使い方 をご覧ください。
※"(Coverage): Error during class instrumentation: org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory: java.lang.NullPointerException" というログが出ており、stackoverflow の Error trying to wire a Lettuce Connection Factory の記事を参考にすれば解決するような気がしますが、一旦無視します。
commit、Push、Pull Request、マージ
ここまでの変更内容を commit します。
コマンドラインから以下のコマンドを実行して commit を1つにまとめます。
> git rebase -i HEAD~8
> git commit --amend -m "#29 貸出希望書籍 CSV ファイルアップロード画面を作成しました。"GitHub へ Push、1.0.x-make-booklist -> 1.0.x へ Pull Request、1.0.x でマージ、1.0.x-make-booklist ブランチを削除、をします。
clean タスクの実行→「Rebuild Project」メニューの実行→build タスクの実行を行い、"BUILD SUCCESSFUL" のメッセージが出力されるかの確認を忘れていたので、ここで確認します。
次回は。。。
最近開発で使用するために書いていた記事を読み返していて、以下の2点が分かりづらかったので改めてまとめ直してみます。
その後で Git for Windows を 2.6.1 にバージョンアップした後、次の貸出状況取得タスクの作成に進みます。
メモ書き
@Autowired で DI したインスタンスの private メソッドの処理だけを JMockit で Mock に出来るのか?
結論として、出来ます。ただし上でテストを作っている時には分かりませんでした。
BooklistService クラスの temporarySaveBookListCsvFile メソッドの中で現在ログイン中のユーザの userId を取得する処理を、ヘルパークラスの LendingUserDetailsHelper.getLoginUserId() ではなく、BooklistService クラス内に getLoginUserId という private メソッドを用意して、BooklistServiceTest で以下のように実装して getLoginUserId メソッドの処理だけ Mock にしようと最初思っていたのですが、この方法ではダメでした。
@Autowired private BooklistService booklistService; @Test public void testTemporarySaveBookListCsvFile() throws Exception { new NonStrictExpectations(booklistService) {{ invoke(booklistService, "getLoginUserId"); result = new Long(1); }};
invoke を呼び出すと booklistService のインスタンスが Mock に変わり、temporarySaveBookListCsvFile メソッドまで Mock メソッドになって実際の処理が呼び出されません。temporarySaveBookListCsvFile メソッド内にブレークポイントを設定してデバッグしても通過しませんでした。
JMockit の Tutorial の Mocking の方ばかり見ていたので正しい方法に気づけなかったのですが、Faking の方を見てやり方が分かりました。
以下の実装で private メソッドのみ Mock メソッドにできます。
@Autowired private BooklistService booklistService; public class MockBooklistService extends MockUp<BooklistService> { @Mock private Long getLoginUserId() { return new Long(1); } } @Test public void testTemporarySaveBookListCsvFile() throws Exception { new MockBooklistService(); UploadBooklistForm uploadBooklistForm = new UploadBooklistForm();
ポイントは以下の通りです。
- @Autowired で DI している部分はそのままで構いません。
- MockUp を利用して一部のメソッドを Mock メソッドにしたいクラスの Mock クラスを定義します。
- 定義した Mock クラスの中で Mock メソッドを @Mock アノテーションを付加して記述します。ここに書いていないメソッドは本来のメソッドが呼び出されます。
- 最後にテストメソッドの最初で、この Mock クラスを new します。
- Mock クラスを new していないテストメソッドでは BooklistService のメソッドは Mock メソッドにはなりません ( 本来のメソッドが呼び出されます )。
ただしまだよく分からないことがあります。上の方法で getLoginUserId メソッドだけ Mock メソッドにしてそれ以外は本来のメソッドが呼び出されているはずなのですが、BooklistService::temporarySaveBookListCsvFile の中にブレークポイントを設定してテストメソッドを Debug モードで実行してもなぜかブレークポイントを通過しない ( 止まらない ) んですよね。まだまだ分からないことがあるんだな。。。 と思いました。
ソースコード
InquiringStatusOfBookQueueServiceTest.java
package ksbysample.webapp.lending.service.queue; import ksbysample.webapp.lending.Application; import ksbysample.webapp.lending.config.Constant; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class InquiringStatusOfBookQueueServiceTest { @Autowired private ConnectionFactory connectionFactory; @Autowired private Queue queue; @Autowired private RabbitTemplate rabbitTemplate; @Autowired private InquiringStatusOfBookQueueService inquiringStatusOfBookQueueService; @Test public void testSendMessage() throws Exception { RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory); rabbitAdmin.deleteQueue(Constant.QUEUE_NAME_INQUIRING_STATUSOFBOOK); rabbitAdmin.declareQueue(queue); Long lendingAppId = new Long(1); inquiringStatusOfBookQueueService.sendMessage(lendingAppId); InquiringStatusOfBookQueueMessage message = (InquiringStatusOfBookQueueMessage) rabbitTemplate.receiveAndConvert(Constant.QUEUE_NAME_INQUIRING_STATUSOFBOOK); assertThat(message.getLendingAppId()).isEqualTo(lendingAppId); } }
table-ordering.txt
user_info user_role library_forsearch lending_app lending_book
- lending_app, lending_book を追加します。
BooklistCsvFileServiceTest.java
public MockMultipartFile createNoErrorCsvFile() throws Exception { ..... } public MockMultipartFile createErrorCsvFile() throws Exception { ..... }
- createNoErrorCsvFile, createErrorCsvFile メソッドを他のテストクラスからも利用したいので private → public へ変更します。
LendingUserDetailsHelper.java
package ksbysample.webapp.lending.security; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; public class LendingUserDetailsHelper { /** * 現在ログインしているユーザのユーザIDを取得する * * @return ユーザID(user_info.user_id) */ public static Long getLoginUserId() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); LendingUserDetails lendingUserDetails = (LendingUserDetails) auth.getPrincipal(); return lendingUserDetails.getUserId(); } }
BooklistService.java
■その1
public Long temporarySaveBookListCsvFile(UploadBooklistForm uploadBooklistForm) { // アップロードされたCSVファイルのデータを List に変換する List<BooklistCSVRecord> booklistCSVRecordList = booklistCsvFileService.convertFileToList(uploadBooklistForm.getFileupload()); // lending_app テーブルにデータを保存する LendingApp lendingApp = new LendingApp(); lendingApp.setStatus(TENPORARY_SAVE.getValue()); lendingApp.setLendingUserId(LendingUserDetailsHelper.getLoginUserId()); lendingAppDao.insert(lendingApp); // lending_book テーブルにデータを保存する LendingBook lendingBook; for (BooklistCSVRecord booklistCSVRecord : booklistCSVRecordList) { lendingBook = new LendingBook(); BeanUtils.copyProperties(booklistCSVRecord, lendingBook); lendingBook.setLendingAppId(lendingApp.getLendingAppId()); lendingBookDao.insert(lendingBook); } return lendingApp.getLendingAppId(); }
- temporarySaveBookListCsvFile メソッドの以下の点を変更します。テスト時に Mock にしたい部分を別クラスのメソッドを呼び出すようにします。
- SecurityContextHolder を利用して LendingUserDetails のインスタンスを取得していた部分を削除します。
lendingApp.setLendingUserId(lendingUserDetails.getUserId());
→lendingApp.setLendingUserId(LendingUserDetailsHelper.getLoginUserId());
へ変更します。
■その2
public void sendMessageToInquiringStatusOfBookQueue(RegisterBooklistForm registerBooklistForm) { inquiringStatusOfBookQueueService.sendMessage(registerBooklistForm.getLendingAppId()); }
- メソッド名を updateLendingAppStatusToPending → sendMessageToInquiringStatusOfBookQueue へ変更します。
table-ordering.txt, lending_app.csv, lending_book.csv
■table-ordering.txt
lending_app lending_book
■lending_app.csv
lending_app_id,status,lending_user_id,approval_user_id 1,1,1,NULL
■lending_book.csv
lending_book_id,lending_app_id,isbn,book_name,lending_state,lending_app_flg,lending_app_reason,approval_result,approval_reason 1,1,978-4-7741-6366-6,GitHub実践入門,NULL,NULL,NULL,NULL,NULL 1,1,978-4-7741-5377-3,JUnit実践入門,NULL,NULL,NULL,NULL,NULL 1,1,978-4-7973-8014-9,Java最強リファレンス,NULL,NULL,NULL,NULL,NULL 1,1,978-4-7973-4778-4,アジャイルソフトウェア開発の奥義,NULL,NULL,NULL,NULL,NULL 1,1,978-4-87311-704-1,Javaによる関数型プログラミング,NULL,NULL,NULL,NULL,NULL
BooklistController.java
@RequestMapping("/register") public String register(RegisterBooklistForm registerBooklistForm , RedirectAttributes redirectAttributes) { booklistService.sendMessageToInquiringStatusOfBookQueue(registerBooklistForm); redirectAttributes.addFlashAttribute("lendingAppId", registerBooklistForm.getLendingAppId()); return "redirect:/booklist/complete"; }
booklistService.updateLendingAppStatusToPending(registerBooklistForm);
→booklistService.sendMessageToInquiringStatusOfBookQueue(registerBooklistForm);
へ変更します。
BooklistServiceTest.java
package ksbysample.webapp.lending.web.booklist; import ksbysample.common.test.TableDataAssert; import ksbysample.common.test.TestDataResource; import ksbysample.webapp.lending.Application; import ksbysample.webapp.lending.entity.LendingBook; import ksbysample.webapp.lending.security.LendingUserDetailsHelper; import ksbysample.webapp.lending.service.file.BooklistCsvFileServiceTest; import mockit.NonStrictExpectations; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.csv.CsvDataSet; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import javax.sql.DataSource; import java.io.File; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class BooklistServiceTest { private final String MAILADDR_TANAKA_TARO = "tanaka.taro@sample.com"; @Rule @Autowired public TestDataResource testDataResource; @Autowired private DataSource dataSource; @Autowired private BooklistService booklistService; @Test public void testTemporarySaveBookListCsvFile() throws Exception { new NonStrictExpectations(LendingUserDetailsHelper.class) {{ LendingUserDetailsHelper.getLoginUserId(); result = new Long(1); }}; UploadBooklistForm uploadBooklistForm = new UploadBooklistForm(); // テスト用のユーティリティクラスを作るべきですが、今回は他のテストクラスのメソッドをそのまま使います BooklistCsvFileServiceTest booklistCsvFileServiceTest = new BooklistCsvFileServiceTest(); uploadBooklistForm.setFileupload(booklistCsvFileServiceTest.createNoErrorCsvFile()); Long lendingAppId = booklistService.temporarySaveBookListCsvFile(uploadBooklistForm); assertThat(lendingAppId).isNotEqualTo(new Long(0)); IDataSet dataSet = new CsvDataSet(new File("src/test/resources/ksbysample/webapp/lending/web/booklist/assertdata/001")); TableDataAssert tableDataAssert = new TableDataAssert(dataSet, dataSource); tableDataAssert.assertEquals("lending_app", new String[]{"lending_app_id", "approval_user_id"}); tableDataAssert.assertEquals("lending_book", new String[]{"lending_book_id", "lending_app_id", "lending_state", "lending_app_flg", "lending_app_reason", "approval_result", "approval_reason"}); List<LendingBook> lendingBookList = booklistService.getLendingBookList(lendingAppId); assertThat(lendingBookList).hasSize(5); } @Test public void testSendMessageToInquiringStatusOfBookQueue() throws Exception { // 現在の実装では InquiringStatusOfBookQueueServiceTest が通ればOKなので、こちらは実装しない } }
- BooklistService クラスの temporarySaveBookListCsvFile メソッドと getLendingBookList メソッドは1つのテストメソッド内でテストした方が効率的なので、別々に分けずにまとめます。
- testSendMessageToInquiringStatusOfBookQueue テストメソッドは InquiringStatusOfBookQueueServiceTest の testSendMessage テストメソッドでテストしたい内容がカバーできているので、実装しません。
BooklistControllerTest.java
■その1
package ksbysample.webapp.lending.web.booklist; import ksbysample.webapp.lending.Application; import org.junit.Test; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(Enclosed.class) public class BooklistControllerTest { @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public static class ユーザ権限とURLの呼び出し可否のテスト { @Test public void ログインしていなければ貸出希望書籍CSVファイルアップロード画面は表示できない() throws Exception { } @Test public void 一般ユーザ権限を持つユーザは貸出希望書籍CSVファイルアップロード画面を表示できる() throws Exception { } @Test public void ログインしていなければアップロード用のURLは呼び出せない() throws Exception { } @Test public void ログインしていなければ確認画面の登録ボタン用のURLは呼び出せない() throws Exception { } } @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public static class ファイルアップロードのテスト_エラーになる場合 { @Test public void エラーが出るCSVファイルをアップロードするとアップロード画面にエラーメッセージを表示する() throws Exception { } } @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public static class ファイルアップロードのテスト_正常な場合 { @Test public void エラーのないCSVファイルをアップロードしてから確認画面で登録ボタンをクリックすると完了画面が表示される() throws Exception { } } }
■その2
package ksbysample.webapp.lending.web.booklist; import ksbysample.common.test.SecurityMockMvcResource; import ksbysample.common.test.TestDataResource; import ksbysample.webapp.lending.Application; import ksbysample.webapp.lending.service.file.BooklistCsvFileServiceTest; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MvcResult; import static ksbysample.common.test.ErrorsResultMatchers.errors; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @RunWith(Enclosed.class) public class BooklistControllerTest { @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public static class ユーザ権限とURLの呼び出し可否のテスト { @Rule @Autowired public TestDataResource testDataResource; @Rule @Autowired public SecurityMockMvcResource mvc; @Test public void ログインしていなければ貸出希望書籍CSVファイルアップロード画面は表示できない() throws Exception { mvc.noauth.perform(get("/booklist")) .andExpect(status().isFound()) .andExpect(redirectedUrl("http://localhost/")); } @Test public void 一般ユーザ権限を持つユーザは貸出希望書籍CSVファイルアップロード画面を表示できる() throws Exception { mvc.authSuzukiHanako.perform(get("/booklist")) .andExpect(status().isOk()) .andExpect(view().name("booklist/booklist")); } @Test public void ログインしていなければアップロード用のURLは呼び出せない() throws Exception { mvc.noauth.perform(post("/booklist/fileupload")) .andExpect(status().isForbidden()); } @Test public void ログインしていなければ確認画面の登録ボタン用のURLは呼び出せない() throws Exception { mvc.noauth.perform(post("/booklist/register")) .andExpect(status().isForbidden()); } } @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public static class ファイルアップロードのテスト_エラーになる場合 { @Rule @Autowired public TestDataResource testDataResource; @Rule @Autowired public SecurityMockMvcResource mvc; @Test public void エラーが出るCSVファイルをアップロードするとアップロード画面にエラーメッセージを表示する() throws Exception { BooklistCsvFileServiceTest booklistCsvFileServiceTest = new BooklistCsvFileServiceTest(); MockMultipartFile multipartFile = booklistCsvFileServiceTest.createErrorCsvFile(); mvc.authSuzukiHanako.perform( fileUpload("/booklist/fileupload") // 単に .file(multipartFile) ではダメで、 // 第1引数に <input type="file" name="..."> の name 属性の文字列を、第2引数にファイルのバイト配列を渡す .file("fileupload", multipartFile.getBytes()) .with(csrf())) .andExpect(status().isOk()) .andExpect(view().name("booklist/booklist")) .andExpect(model().hasErrors()) .andExpect(model().errorCount(6)) .andExpect(errors().hasGlobalError("uploadBooklistForm", "UploadBooklistForm.fileupload.lengtherr")) .andExpect(errors().hasGlobalError("uploadBooklistForm", "UploadBooklistForm.fileupload.isbn.patternerr")) .andExpect(errors().hasGlobalError("uploadBooklistForm", "UploadBooklistForm.fileupload.isbn.lengtherr")) .andExpect(errors().hasGlobalError("uploadBooklistForm", "UploadBooklistForm.fileupload.isbn.numlengtherr")) .andExpect(errors().hasGlobalError("uploadBooklistForm", "UploadBooklistForm.fileupload.isbn.numlengtherr")) .andExpect(errors().hasGlobalError("uploadBooklistForm", "UploadBooklistForm.fileupload.bookname.lengtherr")); } } @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public static class ファイルアップロードのテスト_正常な場合 { @Rule @Autowired public TestDataResource testDataResource; @Rule @Autowired public SecurityMockMvcResource mvc; @Test public void エラーのないCSVファイルをアップロードしてから確認画面で登録ボタンをクリックすると完了画面が表示される() throws Exception { BooklistCsvFileServiceTest booklistCsvFileServiceTest = new BooklistCsvFileServiceTest(); MockMultipartFile multipartFile = booklistCsvFileServiceTest.createNoErrorCsvFile(); // CSVファイルをアップロードする MvcResult result = mvc.authSuzukiHanako.perform( fileUpload("/booklist/fileupload") // 単に .file(multipartFile) ではダメで、 // 第1引数に <input type="file" name="..."> の name 属性の文字列を、第2引数にファイルのバイト配列を渡す .file("fileupload", multipartFile.getBytes()) .with(csrf())) .andExpect(status().isOk()) .andExpect(view().name("booklist/fileupload")) .andExpect(model().hasNoErrors()) .andReturn(); RegisterBooklistForm registerBooklistForm = (RegisterBooklistForm) result.getModelAndView().getModel().get("registerBooklistForm"); // 確認画面で登録ボタンをクリックする mvc.authSuzukiHanako.perform( post("/booklist/register") .param("lendingAppId", registerBooklistForm.getLendingAppId().toString()) .with(csrf())) .andExpect(status().isFound()) .andExpect(redirectedUrl("/booklist/complete")); // 完了画面を表示する mvc.authSuzukiHanako.perform(get("/booklist/complete")) .andExpect(status().isOk()) .andExpect(view().name("booklist/complete")); } } }
OpenWeatherMapApiServiceTest.java
@Ignore("アクセスキーを要求されるようになったのでテストを実行対象外にする") @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class OpenWeatherMapApiServiceTest {
- クラスに
@Ignore("アクセスキーを要求されるようになったのでテストを実行対象外にする")
を付加します。
履歴
2015/10/12
初版発行。