概要
前回の続きです。
https://qiita.com/RYA234/items/40f50205bde33dbb24ac
転職の面接で見せるSpringBootのポートフォリオ作成しています。
現在テストコードで苦戦してるのでUdemyの講座で勉強しています。
今回はSection10:Behavior Driven Mockitoを取り組みました。
内容については大まかに何やってるかを見てもらえれば幸いです。
詳細は講座のほうで確認お願い致します。
Behavior Driven Development(BDD)とは
以下リンクで理解しました。
mockitoはBDDに対応してるみたいです。
なるほど(??ストーリー、シナリオって何だ…?)
mockitoにはGiven,When,Thenに対応する関数があるみたいですね。
環境
OS:windows10(講師はMac使っていたのでMacでもOKです。)
IDE: IntelliJ Community
習得内容given,when,then
github:
フォークしてクローンしました。
branchは「unit-tests」
@ExtendWith(MockitoExtension.class)
class ClinicServiceImplTest {
@Mock
PetRepository petRepository;
@Mock
VetRepository vetRepository;
@Mock
OwnerRepository ownerRepository;
@Mock
VisitRepository visitRepository;
@InjectMocks
ClinicServiceImpl service;
@Test
void findPetTypes() {
//given
List<PetType> petTypeList = new ArrayList<>();
given(petRepository.findPetTypes()).willReturn(petTypeList);
//when
Collection<PetType> returnedPetTypes = service.findPetTypes();
//then
then(petRepository).should().findPetTypes();
assertThat(returnedPetTypes).isNotNull();
}
}
まんま、シナリオのgiven,when,thenですね。 前回の講座だとwhen使ってたけど今回はつかわないのね
デバッグで確認する。
手始めにMockされているか確認します。
ちゃんとMockされてますね。前回の内容ですが念のため確認
詳細の動きを確認したいので43行から50行まで一行一行デバッグしたときの画像を貼ってきます。
43行目実行後
petTypeListのインスタンスが生成され{ArrayList@2743}になります。
44行目実行後
petRepository.findPetTypes()を実行するとpetTypeListが入るようになります。
デバッグ画面的には変化がありません。(見方が悪いかも)
45行目実行後
コメントなのでパス
46行目実行後
returnPetTypeのインスタンスが{ArrayList@2743}として生成されます。
petTypeListも{ArrayList@2473}なので同じ物を指しています。
44行目のgiven()の作用で同じインスタンスを指すようになってますね。
私はこの行の動きは大事だと思います。
returnedPetTypes = (service.findPetTypes()) = petTypeList
47、48行目実行後
空欄、コメントなのでパス
49行目実行後
50行目実行後
ウォッチ式は変化なし
ただのassertThatだから気にならないですね
System.out.printで確認する
ソースコード適当にいじって以下のようにしました。
thenがわからないので重点的に検証しました。
ちなみにこの確認作業は私のアドリブです。講座の内容ではやってないです。
@Test
void findPetTypes() {
//given
List<PetType> petTypeList = new ArrayList<>();
PetType petType = new PetType();
petType.setId(33);
petType.setName("pochi");
petTypeList.add(petType);
given(petRepository.findPetTypes()).willReturn(petTypeList);
//when
Collection<PetType> returnedPetTypes = service.findPetTypes();
//then
then(petRepository).should().findPetTypes();
//コメントには出力結果と感想を書く
System.out.print(then(petRepository) +"\n"); // null thenだけだとnullになるのか…
// System.out.print(then(petRepository).should() +"\n"); //エラー発生 org.mockito.exceptions.base.MockitoException:
// Mockito cannot verify toString()
// 原因不明ですね
System.out.print(then(petRepository).should().findPetTypes() +"\n"); // org.mockito.BDDMockito$ThenImpl@7a48e6e2 ヒントになりそうだがわからん
// System.out.print(then(petRepository).should().findById(1) +"\n"); // エラー発生、Wanted but not invoked: However, there was exactly 1 interaction with this mock:
// givenで前提をしていなかったから?
System.out.print(returnedPetTypes+"\n"); //[pochi] idはどこいったんだ?
System.out.print(petRepository.findPetTypes()+"\n"); //[pochi] idはどこいったんだ?
System.out.print(petRepository+"\n"); //petRepository オブジェクトの名前だけ表示するのね…
assertThat(returnedPetTypes).isNotNull();
}
結果、よくわからんままでしたね。難しい
感想
given良いですね。私が探してたものです。
givenで前提条件を決めれるので今のポートフォーリオで活用できます。
BDDの括り抜きでgiven使います。
あとBDDとかいう概念が初見でした。勉強になります。
thenの動きが理解できてないです。今後の課題にします。
デバッグで動きを確認できるからわかりやすいですね。
有難ぇ…
次やること
次のAdvanced Mockitoはやるかは悩んでいます。
項目的に関係なさそうなんですよね…難しそうだし
もうテストコードがポートフォーリオになってますね(工数的に)