I have a class which associates Products with a ProductCategory. It uses a ProductCategoryRepository which is a MongoDB repository. The ProductCategoryRepository has a findAll methods which takes the productIds of the products and finds their corresponding ProductCategory. However when mock the findAll method in the spock test it fails;
Here is the code for the service
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
@Service
@Slf4j
public class ProductsLinkService {
private final ProductCategoryRepository productCategoryRepository;
@Autowired
public ProductsLinkService(ProductCategoryRepository productCategoryRepository) {
this.productCategoryRepository = productCategoryRepository;
}
public List<Product> process(List<Product> products) {
if (ObjectUtils.isEmpty(products)) {
return new ArrayList<>();
}
List<Long> productIds = MappingUtilityFunctions.retrieveIdsForDepartments(products);
List<ProductCategory> productCategories = productCategoryRepository.findAll(productIds);
return linkProductsWithCategory(products,productCategories);
}
private List<Product> linkProductsWithCategory(List<Product> products, List<ProductCategory> productCategories) {
//...
}
}
The ProductCategoryRepository is a simple class with the findAll method
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public inteface ProductCategoryRepository extends MongoRepository<ProductCategory, Long> {
@Query(value = "{ '_id' : {'$in' : ?0 } }")
List<ProductCategory> findAll(List<Long> productIds);
}
Here is my Spock test for the ProductLinkService
class ProductsLinkServiceSpec extends Specification {
ProductCategoryRepository productCategoryRepository = Mock()
List<Long> productIds = [11L, 22L, 33L]
ProductsLinkService productsLinkService
def setup(){
productsLinkService = new ProductsLinkService(productCategoryRepository)
}
def'Associating products with their product categories should be successful'(){
given:
List<Products> products = ....
List<ProductCategory> productCategories = ...
// Exception thrown here
productCategoryRepository.findAll(productIds) >> productCategories
when:
def productsWithCategories = productsLinkService.process(products)
then:
// assertions
}
}
I get the following error at the at the point where I do the findAll on the ProductCategoryRepository. Here is the exception:
groovy.lang.MissingMethodException: No signature of method: java.util.ArrayList.call() is applicable for argument types: () values: []
Possible solutions: tail(), tail(), wait(), any(), last(), tails()
at com.adx.batch.linking.ProductsLinkServiceSpec.Associating products with their product categories should be successful(ProductsLinkServiceSpec.groovy:25)
This fixed it
productCategoryRepository.findAll(productIds) >> [productCategories[0], etc. ]