SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門
SpringBootTest入門

Editor's Notes

  • #3 2016新卒入社でヤフーショッピングの商品プラットフォーム周りの開発・運用を行っています。 ECサイトで日本一の商品数を誇る商品データPFの管理しています。 趣味でゲームエンジンの開発や、大学時代にはインターネット決済や塾運営システムの開発を行っていました。 Javaの大規模開発経験は今までなかったので、SpringBootの勉強中です。 そこで、SpringBootTestに入門してみました!
  • #4 今回のLTの目標は SpringBootアプリケーションでDIコンテナ管理のBeanについて簡単なテストコードの書き方を理解する としています。 SpringBootTestと書いてありますが、入門のため、SpringBootTest特有の機能の説明ではなく、 JunitとSpringTestの説明になっちゃってますが、ご了承ください。
  • #5 このセッションの目次はこの通りです (目次読む)
  • #7 ご存知だとは思いますが、再確認です。 ユニットテストとは、クラスやメソッドがプログラマの期待通りに振る舞うかを検証することです。 テストコードはクラスやメソッドの仕様書となりうるので、うまく使うと非常に強力です。
  • #9 SpringBootのプロジェクトフォルダ構造はデフォルトでtestパッケージを生成してくれているので、 そこに対象のテストクラスを配置します。
  • #10 テストの実行方法は、コマンドラインからだと./mvnw testと打てば、mavenからテスト可能です。 STSやEclipseからの場合は、プロジェクトを右クリックしてRunAsの中のJUnitTestなどを選択したりすれば実行できます。
  • #11 Eclipseで実行した例としては こんな感じです。
  • #12 Junitにおけるテストケースメソッドの例になります テストパッケージにこのようなメソッドを実装したクラスを生成すると、テスト実行時に自動でテストケースとして実行されます。 詳細としては、
  • #13 @Testアノテーションをつけることで、テストケースの1つとして認識され、実行される。
  • #14 通常のコードで例外の基底クラスであるExceptionをthronwsに指定することはないが、 テストの場合は、複雑になるのを避けるために例外的にExceptionクラスをthrowsに指定する。
  • #15 assertThatメソッドで値が正しいか判定を行います。
  • #16 Matcherオブジェクトと呼ばれるものを生成するMatcherAPIによって述語的に計算値が正しいかどうかを判定することができます。 equalToは一例なので、他にも様々なメソッドを利用できます。
  • #17 AssertJというパッケージを利用することによって、計算値と期待値の比較をメソッドチェーンで記述できます。 メリットとしては、MatcherAPIを覚えていなくても、assertメソッドの後にドットを打てばIDE補完が効くので楽に記述できます。
  • #18 assertThatメソッドではなく、assertほにゃららメソッドはJunitの標準の機能として用意されています。 Junit4では、HamcrestというMatcherオブジェクトパッケージを標準で利用しているために先ほどの書き方になっています。 Junit5では、Matcherオブジェクトを利用するかどうかを、選択することでができるようになり、標準はこちらに戻る方針のようです。
  • #19 テスト対象のクラスの例です。 multiplyメソッドにて、引数で受け取った2つの整数の積を返します。
  • #20 multiplyメソッドのテストの例はこのようになります。 ここが、テストメソッドで、 ここが、テストクラスのインスタンスの生成。 ここで、multiplyメソッドの戻り値を計算した値としてassertionによるチェックを行う
  • #22 SpringBootTestについて、 SpringInitilizrで生成したSpringBootProjectはSpringBootアプリケーションのユニットテストに必要なパッケージは自動で入るように設定されています。
  • #23 Spring-boot-starter-testはこのようなパッケージを含んでいます。 AssertJが先ほどの、メソッドチェーンでチェックできるパッケージ Mamcrestがmatcherオブジェクトライブラリになっているので、先ほどの記法について、 SpringBootでは標準で使えるようになっています。
  • #25 早速、BeanとなっているクラスをDIコンテナを利用せずに単体テスト行う方法についてみてみましょう。 こんな方針でいきます。
  • #26 名前を呼んであいさつのできるメソッドを持つサービスクラスを用意します。 プロパティとして、nameとメッセージを持ち、それぞれはデフォルト値を持ちます。
  • #27 先ほどのサービスクラスをnewでインスタンス生成して、期待値と実際の値を比較し ます。 newして、期待値を作成して、比較する形になります。
  • #28 ここで、疑問が!
  • #29 Newでインスタンス生成を行うと、DIコンテナを利用してないから、他のクラスに依存しているクラスのDIが行われないよね? クラスのプロパティにDIが必要な場合はどうするの? こんな感じでプロパティにAutowiredが指定されているクラスの単体テストの場合ですね!
  • #30 例えば、Diコンテナのコンポーネントスキャンで自動でDIされる、NameGreetingSourceに依存している、DINameGreetingServiceというクラスがいるような場合 先ほどの2つのプロパティを構造体に分離してDIさせた場合です。
  • #31 この場合はDIコンテナを使わずにMockクラスを使ってDIしよう!
  • #32 mockito登場!!! モヒートに由来してるみたいです これは、先ほど説明したspring-boot-starter-testに標準で入っているパッケージです。
  • #33 テストクラスの上にテストランナークラスをアノテーションのオプション指定する InjectされるMockオブジェクトをInjectmocksで指定 InjectするMockオブジェクトをMockで指定
  • #34 MockitoでMockクラスとしたオブジェクトは、メソッドを実際に実行せずにメソッドの振る舞いを引数によって指定できたりします。 詳細はここでは触れませんが、Mockitチュートリアルでご確認ください。
  • #36 SpringBootのDIコンテナを利用して結合テストを行いたい場合
  • #37 BeanのConfigrationクラスを用意して、テストクラスのConfigurationに指定する必要があります。
  • #38 Configurationクラスであることをアノテーションで指定、 ComponentScan対象のパッケージをアノテーションで指定 クラスのメソッドとして、テスト用のBean定義を書くことができます。
  • #39 テストクラスの方は、 DIコンテナを利用するために、Springのテストランナークラスを指定します。 読み込むConfigurationクラスを指定します。 テストクラスにテスト対象クラスをDIして、テストを行います。
  • #40 まとめると、 DIのないBeanの単体テストはJunitの基本的な機能でできます。 DiのあるBeanの単体テストはmockitoを用いたテストでできます。 Beanの結合テストに関しては、テスト用のDIコンテナ設定クラスを読み込んでテストできます。
  • #42 そのまま読みましょう
  • #43 参考文献はこちら