如何测试使用条件查询(使用 spock)的 Grails 服务? [英] How to test a Grails Service that utilizes a criteria query (with spock)?

查看:23
本文介绍了如何测试使用条件查询(使用 spock)的 Grails 服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试一个简单的服务方法.该方法主要只返回一个条件查询的结果,我想测试它是否返回一个结果(取决于查询的内容).

I am trying to test a simple service method. That method mainly just returns the results of a criteria query for which I want to test if it returns the one result or not (depending on what is queried for).

问题是,我不知道如何正确校正相应的测试.我正在尝试通过 spock 来完成它,但是用任何其他测试方式做同样的事情也失败了.

The problem is, that I am unaware of how to right the corresponding test correctly. I am trying to accomplish it via spock, but doing the same with any other way of testing also fails.

谁能告诉我如何修改测试以使其适用于手头的任务?

(顺便说一句,如果可能,我想保持单元测试.)

(BTW I'd like to keep it a unit test, if possible.)

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)

推荐答案

您不应该使用单元测试来测试持久性 - 您只是在测试模拟框架.

You should not use unit tests to test persistence - you're just testing the mocking framework.

相反,将标准查询移动到域类中适当命名的方法,并使用集成测试针对数据库对其进行测试:

Instead, move the criteria query to an appropriately named method in the domain class and test it against a database with an integration test:

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

如果将服务方法作为包装器仍然有价值(例如,如果它实现了一些超出数据库查询的业务逻辑),现在单元测试将很容易,因为模拟静态域类方法是微不足道的调用:

If there's still value in having the service method as a wrapper (e.g. if it implements some business logic above and beyond the database query), it will now be easy to unit test since it's trivial to mock out the static domain class method call:

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

这是合适的,因为您正在测试服务如何使用它接收的数据,并假设集成测试涵盖了检索.

And that's appropriate since you're testing how the service uses the data it receives and assuming that the retrieval is covered in the integration tests.

这篇关于如何测试使用条件查询(使用 spock)的 Grails 服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆