我正在尝试测试一种简单的服务方法。该方法主要只是返回条件查询的结果,我要 测试 该条件查询 是否返回一个结果 (取决于要查询的内容)。
问题是,我不知道如何正确纠正相应的测试。我试图通过spock来实现它,但是用任何其他测试方法进行同样的测试也失败了。
可以告诉我如何修改测试以使其适合当前任务吗?
(顺便说一句,如果可能的话,我想对其进行单元测试。)
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 }
Spock规范
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)
您不应该使用单元测试来测试持久性-您只是在测试模拟框架。
而是将条件查询移动到域类中适当命名的方法,并使用集成测试针对数据库进行测试:
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) } }
如果将service方法作为包装仍然有价值(例如,如果它实现了数据库查询之上和之外的一些业务逻辑),则现在可以轻松进行单元测试,因为可以轻松模拟出静态域类方法调用:
def events = [new Event(...), new Event(...), ...] Event.metaClass.static.findAllEventsByDay = { Date d, int offset, int max -> events }
这是适当的,因为您正在测试服务如何使用其接收的数据,并假设集成测试中涵盖了检索。