Как проверить службу Grails, которая использует запрос критериев (с помощью spock)?
Я пытаюсь протестировать простой метод службы. Этот метод в основном просто возвращает результаты запроса критериев, для которого я хочу проверить, возвращает ли он один результат или нет (в зависимости от того, что запрашивается для).
Проблема в том, что я не знаю, как правильно правильно выполнить соответствующий тест. Я пытаюсь выполнить его с помощью spock, но делать то же самое с любым другим способом тестирования также не удается.
Можно ли мне сказать, как изменить тест, чтобы заставить его работать под задачу?
(Кстати, я хотел бы сохранить его unit test, если это возможно.)
Метод EventService
public HashSet<Event> listEventsForDate(Date date, int offset, int max) {
date.clearTime()
def c = Event.createCriteria()
def results = c {
and {
le("startDate", date+1) // starts tonight at midnight or prior?
ge("endDate", date) // ends today or later?
}
maxResults(max)
order("startDate", "desc")
}
return results
}
Спецификация Спока
package myapp
import grails.plugin.spock.*
import spock.lang.*
class EventServiceSpec extends Specification {
def event
def eventService = new EventService()
def setup() {
event = new Event()
event.publisher = Mock(User)
event.title = 'et'
event.urlTitle = 'ut'
event.details = 'details'
event.location = 'location'
event.startDate = new Date(2010,11,20, 9, 0)
event.endDate = new Date(2011, 3, 7,18, 0)
}
def "list the Events of a specific date"() {
given: "An event ranging over multiple days"
when: "I look up a date for its respective events"
def results = eventService.listEventsForDate(searchDate, 0, 100)
then: "The event is found or not - depending on the requested date"
numberOfResults == results.size()
where:
searchDate | numberOfResults
new Date(2010,10,19) | 0 // one day before startDate
new Date(2010,10,20) | 1 // at startDate
new Date(2010,10,21) | 1 // one day after startDate
new Date(2011, 1, 1) | 1 // someday during the event range
new Date(2011, 3, 6) | 1 // one day before endDate
new Date(2011, 3, 7) | 1 // at endDate
new Date(2011, 3, 8) | 0 // one day after endDate
}
}
Ошибка
groovy.lang.MissingMethodException: No signature of method: static myapp.Event.createCriteria() is applicable for argument types: () values: []
at myapp.EventService.listEventsForDate(EventService.groovy:47)
at myapp.EventServiceSpec.list the Events of a specific date(EventServiceSpec.groovy:29)
Ответы
Ответ 1
Вы не должны использовать модульные тесты для проверки настойчивости - вы просто проверяете насмешливую структуру.
Вместо этого переместите запрос критериев на соответствующий метод в классе домена и протестируйте его с базой данных с тестом интеграции:
class Event {
...
static Set<Event> findAllEventsByDay(Date date, int offset, int max) {
...
}
}
class EventService {
Set<Event> listEventsForDate(Date date, int offset, int max) {
...
return Event.findAllEventsByDay(date, offset, max)
}
}
Если значение метода службы в качестве обертки по-прежнему имеет значение (например, если оно реализует некоторую бизнес-логику выше и выше запроса к базе данных), теперь будет легко unit test, поскольку это тривиально, чтобы издеваться над статическим классом домена вызов метода:
def events = [new Event(...), new Event(...), ...]
Event.metaClass.static.findAllEventsByDay = { Date d, int offset, int max -> events }
И это необходимо, так как вы тестируете, как служба использует полученные данные, и полагая, что поиск проверяется в тестах интеграции.
Ответ 2
Запросы критериев не поддерживаются в модульных тестах. Из документации mockDomain:
[T] он плагин не поддерживает насмешку критериев или запросов HQL. Если вы используете любой из них, просто макет соответствующих методов вручную (например, с помощью mockFor()) или используйте тест интеграции с реальными данными.
Вам нужно будет сделать свой тест интеграционным тестом. Вы увидите, что исключение исчезнет, если вы переместите тест из папки test/unit в папку test/integration.
В модульных тестах проводится определенная работа по поддержке критериев, и если вы чувствуете себя авантюрно, вы можете попробовать ее сегодня. См. Это обсуждение списка рассылки DatastoreUnitTestMixin.