UT(ユニットテスト)時に、@Mockを使用することでAutowiredされたクラスをMockして自由に振る舞いを決めることができる。
@Mockを使うことで外部に依存しない、テストしたいクラスだけに注力することができる。
@Mockを使う時にはおまじないが必要になるので、MockitoExtensionやinitMocksを使用しなければならない。
Maven
MockitoExtensionを使用するために、Dependencyをpom.xmlに追加しておく。
initMocks
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を使用すると
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オブジェクトを初期化しているよう...。
MockitoExtension
MockitoExtensionを使用すると
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したいのかわからないので、引数として渡してあげる必要がある。
MockitoExtension + InjectMocks
MockitoExtensionとInjectMocksを合わせることもできる。
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する必要がなくなる。