LoginSignup
0
0

More than 3 years have passed since last update.

Map→List時にMethodが呼ばれたかをMockitoで確認する(when,verify)

Last updated at Posted at 2019-08-12

Stubにしたメソッドが決められた引数で呼ばれているのかをMockitoのverifyを使うことで確認することができるが、Mapを使用しているときはランダムになるため普通のverifyでは通用しなくなるのでArgumentMatcherのargThatを使用して引数の検証を行う。

Maven

ArgumentMatcherのargThatを使用できるように、Dependencyをpom.xmlに追加しておく。

例えば...

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
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(Map map) {
    List<String> updateList = new ArrayList<>(map.keySet()); // 順番がランダムなListになる
    godRepository.update(updateList);
  }
}

のテストを以下のように作成して

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

import java.util.HashMap;
import java.util.Map;
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
  private GodRepository godRepository;

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

  @Test
  void update() {
    when(godRepository.update(asList("2a", "3b", "1c", "4d"))).thenReturn(4);

    Map<String, String> updateMap = new HashMap<>();
    updateMap.put("2a", "1");
    updateMap.put("3b", "2");
    updateMap.put("1c", "3");
    updateMap.put("4d", "4");
    godService.update(updateMap);

    verify(godRepository).update(asList("2a", "3b", "1c", "4d"));
  }
}

テストを実行すると

org.mockito.exceptions.misusing.PotentialStubbingProblem: 
Strict stubbing argument mismatch. Please check:
 - this invocation of 'update' method:
    godRepository.update([4d, 1c, 2a, 3b]);

引数の順番が違うと言われる。

ArgumentMatcher

そこでArgumentMatcherのargThatを使用して引数の検証も行う。

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

import java.util.HashMap;
import java.util.Map;
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
  private GodRepository godRepository;

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

  @Test
  void update() {
    // containsAllだけでは引数が3つでも通過してしまうのでsizeで回避する
    when(godRepository.update(argThat(list -> list.size() == 4 &&
        list.containsAll(asList("2a", "3b", "1c", "4d"))))).thenReturn(4);

    Map<String, String> updateMap = new HashMap<>();
    updateMap.put("2a", "1");
    updateMap.put("3b", "2");
    updateMap.put("1c", "3");
    updateMap.put("4d", "4");
    godService.update(updateMap);

    verify(godRepository).update(argThat(list -> list.size() == 4 &&
        list.containsAll(asList("2a", "3b", "1c", "4d"))));
  }
}
0
0
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
0
0