I'm trying to unit test a service method that ultimately makes a call to the Criteria API's distinct(Collection) method (i.e., it calls the version of distinct() that takes a Collection). I'm getting the following error:
No signature of method: greenfield224.BookService.distinct() is applicable for argument types: (java.util.ArrayList) values: [[id, author, title, publisher]]
If I change the service method such that it uses the version of distinct() that accepts a single String property name, I do not get an error. But if that single property name is 'id', it returns nothing in the unit test.
I'm wondering if this is a bug in the Grails 2.2.4 test framework, or if I'm just not understanding something. Maybe using the distinct() method is not supported for unit tests? (An equivalent integration test works fine, by the way). Here is some example code that demonstrates the problem:
class Book {
Long id
String subject
String author
String publisher
String title
static constraints = {
subject nullable: true
author nullable: true
publisher nullable: true
title nullable: true
}
}
class BookService {
def findSimilarBooks(Book book) {
def results = Book.withCriteria {
eq('subject', book.subject)
order('title')
order('author')
projections {
//this line blows up in a unit test
distinct(['id', 'author', 'title', 'publisher'])
}
}
return results.collect {
[id:it[0], author:it[1], title:it[2], publisher:it[3]]
}
}
}
@TestFor(BookService)
@Mock(Book)
class BookServiceSpec extends Specification {
def "findSimilarBooks works properly"() {
setup:
def math = new Book(id:1, title:"Mathematics for Nonmathematicians", subject: "Math", author:"Morris Kline", publisher:"Somehouse")
def philosophy = new Book(id:2, title:"The Problems of Philosophy", subject: "Philosophy", author:"Bertrand Russell", publisher:"Ye Olde House of Mutton")
def investing = new Book(id:3, title:"The Intelligent Investor", subject: "investing", author:"Ben Graham", publisher:"Investors Anonymous")
def qed = new Book(id:4, title:"Q.E.D.", subject: "Math", author:"Burkard Polster", publisher: "Wooden Books")
def books = [math, philosophy, investing, qed]
books*.save(failOnError: true)
when:
def results = service.findSimilarBooks(math)
then:
results.size() == 2
}
}