Mockitoが難しいのでUdemyで勉強しました ②

# 概要
前回の続きです。
https://qiita.com/RYA234/items/40f50205bde33dbb24ac

転職の面接で見せるSpringBootのポートフォリオ作成しています。
現在テストコードで苦戦してるのでUdemyの講座で勉強しています。
今回はSection10:Behavior Driven Mockitoを取り組みました。
内容については大まかに何やってるかを見てもらえれば幸いです。
詳細は講座のほうで確認お願い致します。

https://www.udemy.com/course/testing-spring-boot-beginner-to-guru/

# Behavior Driven Development（BDD）とは
以下リンクで理解しました。
mockitoはBDDに対応してるみたいです。

https://shiftasia.com/ja/column/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8Btdd%E3%81%A8bdd/#:~:text=BDD%E3%81%AFTDD%E3%82%92%E6%8B%A1%E5%BC%B5,%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

抜粋した画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/f032995c-fde8-ac85-a4ec-7237d43d0df9.png)

なるほど（？？ストーリー、シナリオって何だ…？）
mockitoにはGiven,When,Thenに対応する関数があるみたいですね。

# 環境
OS:windows10(講師はMac使っていたのでMacでもOKです。)
IDE: IntelliJ Community


# 習得内容given,when,then
github：
フォークしてクローンしました。

https://github.com/springframeworkguru/tb2g-bdd-mockito



branchは「unit-tests」

```ClinicServiceImplTest.java 
@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されているか確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/950ccaf3-6f6b-5144-d77f-841012c61507.png)
ちゃんとMockされてますね。前回の内容ですが念のため確認


詳細の動きを確認したいので43行から50行まで一行一行デバッグしたときの画像を貼ってきます。

43行目実行後
petTypeListのインスタンスが生成され{ArrayList@2743}になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/f4f88667-a05c-a7e9-165b-740326a68216.png)


44行目実行後
petRepository.findPetTypes()を実行するとpetTypeListが入るようになります。
デバッグ画面的には変化がありません。（見方が悪いかも）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0b5ca351-4b87-b54d-cd6c-1d91ec621d9a.png)

45行目実行後
コメントなのでパス

46行目実行後
returnPetTypeのインスタンスが{ArrayList@2743}として生成されます。
petTypeListも{ArrayList@2473}なので同じ物を指しています。
44行目のgiven()の作用で同じインスタンスを指すようになってますね。
私はこの行の動きは大事だと思います。

**returnedPetTypes** = (**service.findPetTypes()**) = **petTypeList** 


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/26b78e1b-1aea-783c-17c0-6468ac6201c6.png)

47、48行目実行後
空欄、コメントなのでパス

49行目実行後

ウォッチ式は変化なし
thenの動きがわからんですね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/3db167b2-16ac-583e-31a2-23133ae7fad1.png)


50行目実行後
ウォッチ式は変化なし
ただのassertThatだから気にならないですね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/f12d551c-5f6f-78f7-c552-c6a85149a173.png)

## System.out.printで確認する
ソースコード適当にいじって以下のようにしました。
thenがわからないので重点的に検証しました。
ちなみにこの確認作業は私のアドリブです。講座の内容ではやってないです。

```ClinicServiceImplTest.java 
    @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はやるかは悩んでいます。
項目的に関係なさそうなんですよね…難しそうだし
もうテストコードがポートフォーリオになってますね（工数的に）