AutowiredされるクラスをMockしてTestする(MockitoExtension, initMocks)

UT(ユニットテスト)時に、@Mockを使用することでAutowiredされたクラスをMockして自由に振る舞いを決めることができる。
@Mockを使うことで外部に依存しない、テストしたいクラスだけに注力することができる。
@Mockを使う時にはおまじないが必要になるので、MockitoExtensionやinitMocksを使用しなければならない。

## <u>Maven</u>
[MockitoExtension](https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api)を使用するために、Dependencyをpom.xmlに追加しておく。

## <font color="Black"><u>initMocks</u></font>
```java
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor // コンストラクタを使用せずにGodRepositoryをAutowiredする
public class GodServiceImpl implements GodService {

  private final GodRepository godRepository; // RequiredArgsConstructorを使用する時はfinalにする

  @Override
  public void update(List updateList) {
    godRepository.update(updateList);
  }
}
```
のテストでinitMocksを使用すると

```java
import static java.util.Arrays.asList;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

class GodServiceImplTest {

  @InjectMocks // Mockしたクラスを使用しているクラス
  private GodServiceImpl godServiceImpl;

  @Mock // Mockしたいクラス
  private GodRepository godRepository;

  @BeforeEach
  public void setUp() {
    initMocks(this); // おまじない
  }

  @Test
  void update() {
    List<String> updateList = asList("a", "b", "c", "d");
    when(godRepository.update(updateList)).thenReturn(4);

    godServiceImpl.update(updateList);

    verify(godRepository).update(updateList);
  }
}
```
initMocksでMockオブジェクトを初期化しているよう...。

## <font color="Black"><u>MockitoExtension</u></font>
MockitoExtensionを使用すると

```java
import static java.util.Arrays.asList;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class) // おまじない
class GodServiceImplTest {

  private GodService godService;

  @Mock // Mockしたいクラス
  private GodRepository godRepository;

  @BeforeEach
  public void setUp() {
    godService = new GodServiceImpl(godRepository); // MockしたGodRepositoryをInjectする
  }

  @Test
  void update() {
    List<String> updateList = asList("a", "b", "c", "d");
    when(godRepository.update(updateList)).thenReturn(4);

    godService.update(updateList);

    verify(godRepository).update(updateList);
  }
}
```
ただMockしただけでは、どのクラスで使われているクラスをMockしたいのかわからないので、引数として渡してあげる必要がある。

## <font color="Black"><u>MockitoExtension + InjectMocks</u></font>
MockitoExtensionとInjectMocksを合わせることもできる。

```java
import static java.util.Arrays.asList;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class) // おまじない
class GodServiceImplTest {

  @InjectMocks // Mockしたクラスを使用しているクラス
  private GodServiceImpl godServiceImpl;

  @Mock // Mockしたいクラス
  private GodRepository godRepository;

  @Test
  void update() {
    List<String> updateList = asList("a", "b", "c", "d");
    when(godRepository.update(updateList)).thenReturn(4);

    godServiceImpl.update(updateList);

    verify(godRepository).update(updateList);
  }
}
```
BeforeEachでMockオブジェクトをいちいちInjectする必要がなくなる。