LoginSignup
3
1

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-08-15

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する必要がなくなる。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1