Как проверить сервис Grails, который использует запрос критериев (с помощью spock)? - PullRequest
11 голосов
/ 08 марта 2011

Я пытаюсь протестировать простой метод обслуживания.Этот метод в основном просто возвращает результаты запроса критерия, для которого я хочу проверить, возвращает ли он один результат или нет (в зависимости от того, что запрашивается).

Проблема в том,что я не знаю, как правильно исправить соответствующий тест.Я пытаюсь выполнить его с помощью спока, но выполнить то же самое с любым другим способом тестирования также не удается.

Можно ли мне сказать, как изменить тест, чтобы он работал для задачи врука?

(Кстати, я бы хотел, чтобы это был тестовый модуль, если это возможно.)

Метод 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)

Ответы [ 2 ]

17 голосов
/ 09 марта 2011

Вы не должны использовать модульные тесты для проверки персистентности - вы просто тестируете фальшивую инфраструктуру.

Вместо этого переместите запрос критериев в метод с соответствующим именем в классе домена и протестируйте его в базе данных с помощьюинтеграционный тест:

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)
   }
}

Если все еще имеет значение наличие метода службы в качестве оболочки (например, если он реализует некоторую бизнес-логику выше и за пределами запроса к базе данных), теперь будет легко выполнить модульное тестирование, посколькутривиально вызывать вызов метода статического класса домена:

def events = [new Event(...), new Event(...), ...]
Event.metaClass.static.findAllEventsByDay = { Date d, int offset, int max -> events }

И это уместно, поскольку вы проверяете, как служба использует данные, которые она получает, и предполагаете, что извлечение включено в интеграционные тесты.

4 голосов
/ 08 марта 2011

Критерии запросов не поддерживаются в модульных тестах. Из документации mockDomain :

[T] Плагин не поддерживает макетирование критериев или HQL-запросов. Если вы используете любой из них, просто смоделируйте соответствующие методы вручную (например, с помощью mockFor ()) или используйте интеграционный тест с реальными данными.

Вы должны будете сделать свой тест интеграционным тестом. Вы увидите, что исключение исчезнет, ​​если вы переместите тест из папки test / unit в папку test / интеграции.

В модульных тестах проводится некоторая работа по поддержке критериев, и если вы чувствуете себя авантюрным, вы можете попробовать это сегодня. См. Это обсуждение списка рассылки DatastoreUnitTestMixin .

...