I have written unit tests for my class and they seem to run fine. But the challenge is I can't get full coverage or get the builder.and(...) operation part to execute or be covered.
Any idea what could be going on? Thank you
This is the utility class to create Predicates
import static java.util.Objects.nonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.persistence.criteria.Predicate;
import lombok.experimental.UtilityClass;
import org.springframework.data.jpa.domain.Specification;
@UtilityClass
public class UsersSearchSpecificationFactory {
public static Specification<User> createSpecification(UsersSearchCriteria criteria) {
final List<Specification<User>> specificationList = new ArrayList<>();
if (nonNull(criteria.getAge()))
specificationList.add(ageSpecification(criteria.getAge()));
if (nonNull(criteria.getAccountType()))
specificationList.add(accountTypeSpecification(criteria.getAccountType()));
if (nonNull(criteria.getAge())) {
specificationList.add(idSpecification(criteria.getId()));
}
return (root, query, builder) -> {
return builder.and(
specificationList.stream()
.map(specification -> specification.toPredicate(root, query, builder))
.toArray(Predicate[]::new)
);
};
}
private static Specification<User> ageSpecification(String value) {
return (root, query, builder) -> builder.isMember(value, root.get("age"));
}
private static Specification<User> accountTypeSpecification(String value) {
return (root, query, builder) -> builder.equal(root.get("accountType"), value);
}
private static Specification<User> idSpecification(UUID value) {
return (root, query, builder) -> builder.equal(root.get("id"), value);
}
}
This is the Repository interface:
import java.util.UUID;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
interface UserRepository extends CrudRepository<User, UUID>, JpaSpecificationExecutor<User> {
Page<User> findAll(UsersSearchCriteria criteria, Orderable orderable, PageRequest pageable);
}
The Spock Specification logic is in here
import javax.persistence.EntityManager
import javax.persistence.PersistenceContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager
@DataJpaTest
@AutoConfigureTestDatabase
class DatabaseSpecification extends InternalSpecification{
@Autowired
private TestEntityManager tem
@PersistenceContext
private EntityManager em
protected <T> T persist(T entity) {
final persisted = tem.persistAndFlush(entity)
tem.detach(persisted)
return persisted
}
}
This is my test:
import static java.util.UUID.randomUUID
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.PageRequest
class UserRepositoryTest extends DatabaseSpecification {
def "should_find_user"() {
given:
userRepository = Mock(UserRepository)
and:
final user = Mock(User) as Specification
final criteria = new UserSearchCriteria(
filter: 'userFilter',
id: 'id'
)
final orderable = new orderable()
final pageable = new pageable()
when:
final foundUser = userRepositoryImpl.findAll(criteria, orderable, pageable)
then:
1 * userRepositoryImpl.repository.findAll(_ as Specification, _ as Pageable) >> new PageImpl<>([user])
and:
foundUser.content.get(0) == user
}
}