You can check if the Stub method is called with a fixed argument by using Mockito's verify, but when using Map it will be random and will not work with normal verify. Validate the arguments using argThat of ArgumentMatcher.
Maven Add Dependency to pom.xml so that you can use ArgumentMatcher's argThat.
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor //Autowired God Repository without using a constructor
public class GodServiceImpl implements GodService {
private final GodRepository godRepository; //Final when using RequiredArgsConstructor
@Override
public void update(Map map) {
List<String> updateList = new ArrayList<>(map.keySet()); //List in random order
godRepository.update(updateList);
}
}
Create a test of
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) //Omit necessary settings, etc.
class GodServiceImplTest {
private GodService godService;
@Mock
private GodRepository godRepository;
@BeforeEach
public void setUp() {
godService = new GodServiceImpl(godRepository); //Inject the Mocked God Repository
}
@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"));
}
}
When you run the test
org.mockito.exceptions.misusing.PotentialStubbingProblem:
Strict stubbing argument mismatch. Please check:
- this invocation of 'update' method:
godRepository.update([4d, 1c, 2a, 3b]);
It is said that the order of the arguments is different.
ArgumentMatcher Therefore, argument validation is also performed using argThat of ArgumentMatcher.
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) //Omit necessary settings, etc.
class GodServiceImplTest {
private GodService godService;
@Mock
private GodRepository godRepository;
@BeforeEach
public void setUp() {
godService = new GodServiceImpl(godRepository); //Inject the Mocked God Repository
}
@Test
void update() {
//If only containsAll, even 3 arguments will pass, so avoid it with 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"))));
}
}