Я пишу юнит-тесты для контроллера и высмеиваю все вызовы его службы. Я использую Spring с репозиторием JPA.
@RestController
@CrossOrigin
@RequestMapping("/somerequest")
public class MyController {
@Autowired
UserService userService;
....
@RequestMapping("/filter")
public List<UserDTO> getUsersByFilter(@RequestParam(value = "search") String search) {
UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),", Pattern.UNICODE_CHARACTER_CLASS);
Matcher matcher = pattern.matcher(search + ",");
while (matcher.find()) {
builder.with(matcher.group(1), SearchOperation.getSimpleOperation(matcher.group(2)), matcher.group(3));
}
Specification<User> spec = builder.build();
List<User> result = userService.getUserByFilter(spec);
List<UserDTO> userDtoList = new ArrayList<UserDTO>();
if (!result.isEmpty()) {
for (User a : result) {
userDtoList.add(convertToDTO(a));
}
}
return userDtoList;
}
....
}
Как я могу (Mockito) проверить, с какими параметрами вызывается метод getUserByFilter? Я использовал ArgumentCaptor, чтобы поймать объект спецификации, который передается методу, но я не знаю, как получить критерии поиска из него. Большое спасибо за вашу помощь
public class UserSpecificationsBuilder {
private final List<SearchCriteria> params;
public UserSpecificationsBuilder() {
params = new ArrayList<SearchCriteria>();
}
public UserSpecificationsBuilder with(String key, SearchOperation operation, Object value) {
params.add(new SearchCriteria(key, operation, value));
return this;
}
public Specification<User> build() {
if (params.size() == 0) {
return null;
}
List<Specification> specs = params.stream().map(UserSpecification::new).collect(Collectors.toList());
Specification<User> result = specs.get(0);
for (int i = 1; i < params.size(); i++) {
result = Specification.where(result).and(specs.get(i));
}
return result;
}
}
public class UserSpecification implements Specification<User> {
/**
*
*/
private static final long serialVersionUID = 1L;
private SearchCriteria criteria;
public UserSpecification(SearchCriteria criteria) {
this.criteria = criteria;
}
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
switch (criteria.getOperation()) {
case LIKE:
return builder.like(root.get(criteria.getKey()), "%" + criteria.getValue().toString() + "%");
case GREATER_THAN:
return builder.greaterThan(root.get(criteria.getKey()), criteria.getValue().toString());
case LESS_THAN:
return builder.lessThan(root.get(criteria.getKey()), criteria.getValue().toString());
default:
return null;
}
}
@Override
public boolean equals(Object obj) {
UserSpecification source = (UserSpecification) obj;
if (source.criteria != null) {
return this.criteria.equals(source.criteria);
}
return false;
}
}
public class SearchCriteria {
private String key;
private SearchOperation operation;
private Object value;
public SearchCriteria(final String key, final SearchOperation operation, final Object value) {
super();
this.key = key;
this.operation = operation;
this.value = value;
}
@Override
public boolean equals(Object obj) {
SearchCriteria source = (SearchCriteria) obj;
return this.key.equals(source.getKey()) && this.value.toString().equals(source.getValue().toString())
&& this.operation.equals(source.getOperation());
}
// getters and setters
}
Мой тест:
@ContextConfiguration(classes = Application.class)
@WebMvcTest(UserController.class)
@DisplayName("UserController - Test")
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
...
@Test
void testGetUsererByFilter() throws Exception {
ArgumentCaptor<Specification> argsCaptor = ArgumentCaptor.forClass(Specification.class);
String filterURL = "/filter?search=personalnummer:6517,ueberstd>5";
given(this.userService.getUserByFilter(any(Specification.class)))
.willReturn(new ArrayList<User>());
mockMvc.perform(get(requestURL + filterURL)).andExpect(status().isOk())
.andExpect(handler().handlerType(UserController.class))
.andExpect(handler().methodName("getUserByFilter"));
UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
UserSpecification spec1 = new UserSpecification(new SearchCriteria("personalnummer", SearchOperation.LIKE, "6517"));
builder.with(spec1);
UserSpecification spec2 = new UserSpecification(new SearchCriteria("ueberstd", SearchOperation.GREATER_THAN, "5"));
builder.with(spec2);
Specification<User> spec = builder.build();
verify(this.userService, times(1)).getUserByFilter(spec);
// verify(this.UsernehmerService, times(1)).getUserByFilter(argsCaptor.capture());
// List<Specification> capturedArgs = argsCaptor.getAllValues();
// assertEquals(Specification.where(spec1).and(spec2), Specification.where(capturedArgs.get(0)));
}
}
и UserService:
@Service
public class UserService {
@Autowired
UserRepository userRepository;
public List<User> getUserByFilter(Specification<User> spec) {
List<User> userList = userRepository.findAll(spec);
return userList;
}
}